Merge "Add metrics to CrossProfileApps methods." into qt-dev
diff --git a/api/system-current.txt b/api/system-current.txt
index e479c48..36680a1 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1635,7 +1635,7 @@
method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryIntentServicesAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle);
method public abstract void registerDexModule(@NonNull String, @Nullable android.content.pm.PackageManager.DexModuleRegisterCallback);
method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void removeOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener);
- method @Deprecated public void replacePreferredActivity(@NonNull android.content.IntentFilter, int, @NonNull java.util.List<android.content.ComponentName>, @NonNull android.content.ComponentName);
+ method public void replacePreferredActivity(@NonNull android.content.IntentFilter, int, @NonNull java.util.List<android.content.ComponentName>, @NonNull android.content.ComponentName);
method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
method public void sendDeviceCustomizationReadyBroadcast();
method @RequiresPermission(allOf={android.Manifest.permission.SET_PREFERRED_APPLICATIONS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public abstract boolean setDefaultBrowserPackageNameAsUser(@Nullable String, int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 77c3a94..aacf2c1 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3205,6 +3205,7 @@
method public default void setShouldShowIme(int, boolean);
method public default void setShouldShowSystemDecors(int, boolean);
method public default void setShouldShowWithInsecureKeyguard(int, boolean);
+ method public default boolean shouldShowIme(int);
method public default boolean shouldShowSystemDecors(int);
}
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 2bd4299..318d90c 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -3296,7 +3296,10 @@
INSTALL_STAGED_NOT_READY = 3;
INSTALL_STAGED_READY = 4;
INSTALL_SUCCESS = 5;
- INSTALL_FAILURE = 6;
+ // Replaced by INSTALL_FAILURE_DOWNLOAD, INSTALL_FAILURE_STATE_MISMATCH,
+ // and INSTALL_FAILURE_COMMIT.
+ INSTALL_FAILURE = 6 [deprecated = true];
+ // This enum is for installs that are manually cancelled via the Manual Update UI.
INSTALL_CANCELLED = 7;
INSTALLER_ROLLBACK_REQUESTED = 8;
INSTALLER_ROLLBACK_INITIATED = 9;
@@ -3313,6 +3316,9 @@
INSTALL_STAGED_CANCEL_REQUESTED = 20;
INSTALL_STAGED_CANCEL_SUCCESS = 21;
INSTALL_STAGED_CANCEL_FAILURE = 22;
+ INSTALL_FAILURE_DOWNLOAD = 23;
+ INSTALL_FAILURE_STATE_MISMATCH = 24;
+ INSTALL_FAILURE_COMMIT = 25;
}
optional State state = 6;
// Possible experiment ids for monitoring this push.
@@ -5863,7 +5869,10 @@
INSTALL_STAGED_NOT_READY = 3;
INSTALL_STAGED_READY = 4;
INSTALL_SUCCESS = 5;
- INSTALL_FAILURE = 6;
+ // Replaced by INSTALL_FAILURE_DOWNLOAD, INSTALL_FAILURE_STATE_MISMATCH,
+ // and INSTALL_FAILURE_COMMIT.
+ INSTALL_FAILURE = 6 [deprecated = true];
+ // This enum is for installs that are manually cancelled via the Manual Update UI.
INSTALL_CANCELLED = 7;
INSTALLER_ROLLBACK_REQUESTED = 8;
INSTALLER_ROLLBACK_INITIATED = 9;
@@ -5880,6 +5889,9 @@
INSTALL_STAGED_CANCEL_REQUESTED = 20;
INSTALL_STAGED_CANCEL_SUCCESS = 21;
INSTALL_STAGED_CANCEL_FAILURE = 22;
+ INSTALL_FAILURE_DOWNLOAD = 23;
+ INSTALL_FAILURE_STATE_MISMATCH = 24;
+ INSTALL_FAILURE_COMMIT = 25;
}
optional Status status = 4;
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a95e094..33c0bb9 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -6178,15 +6178,7 @@
* @param activity The component name of the activity that is to be preferred.
*
* @hide
- *
- * @deprecated This function no longer does anything. It is the platform's
- * responsibility to assign preferred activities and this cannot be modified
- * directly. To determine the activities resolved by the platform, use
- * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure
- * an app to be responsible for a particular role and to check current role
- * holders, see {@link android.app.role.RoleManager}.
*/
- @Deprecated
@SystemApi
public void replacePreferredActivity(@NonNull IntentFilter filter, int match,
@NonNull List<ComponentName> set, @NonNull ComponentName activity) {
diff --git a/core/java/android/database/MatrixCursor.java b/core/java/android/database/MatrixCursor.java
index a52e96e..b0d399c 100644
--- a/core/java/android/database/MatrixCursor.java
+++ b/core/java/android/database/MatrixCursor.java
@@ -18,6 +18,7 @@
import android.annotation.UnsupportedAppUsage;
import android.os.Build;
+
import java.util.ArrayList;
/**
@@ -240,6 +241,12 @@
}
return this;
}
+
+ /** @hide */
+ public final RowBuilder add(int columnIndex, Object value) {
+ data[(row * columnCount) + columnIndex] = value;
+ return this;
+ }
}
// AbstractCursor implementation.
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 94c8b91..3a4741a 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -978,11 +978,6 @@
*/
public static final int Q = CUR_DEVELOPMENT;
- /**
- * Stub for a potential new API level after P.
- * @hide
- */
- public static final int P0 = Q;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 1aa5b06..2a41c20 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -23,11 +23,8 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
-import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.pm.PermissionInfo;
import android.os.RemoteException;
import com.android.internal.annotations.Immutable;
@@ -107,11 +104,11 @@
/**
* Get set of permissions that have been split into more granular or dependent permissions.
*
- * <p>E.g. before {@link android.os.Build.VERSION_CODES#P0} an app that was granted
+ * <p>E.g. before {@link android.os.Build.VERSION_CODES#Q} an app that was granted
* {@link Manifest.permission#ACCESS_COARSE_LOCATION} could access he location while it was in
- * foreground and background. On platforms after {@link android.os.Build.VERSION_CODES#P0}
+ * foreground and background. On platforms after {@link android.os.Build.VERSION_CODES#Q}
* the location permission only grants location access while the app is in foreground. This
- * would break apps that target before {@link android.os.Build.VERSION_CODES#P0}. Hence whenever
+ * would break apps that target before {@link android.os.Build.VERSION_CODES#Q}. Hence whenever
* such an old app asks for a location permission (i.e. the
* {@link SplitPermissionInfo#getSplitPermission()}), then the
* {@link Manifest.permission#ACCESS_BACKGROUND_LOCATION} permission (inside
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 8a21806..b0e980e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11961,6 +11961,36 @@
public static final String JOB_SCHEDULER_CONSTANTS = "job_scheduler_constants";
/**
+ * Job scheduler QuotaController specific settings.
+ * This is encoded as a key=value list, separated by commas. Ex:
+ *
+ * "max_job_count_working=5,max_job_count_rare=2"
+ *
+ * <p>
+ * Type: string
+ *
+ * @hide
+ * @see com.android.server.job.JobSchedulerService.Constants
+ */
+ public static final String JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS =
+ "job_scheduler_quota_controller_constants";
+
+ /**
+ * Job scheduler TimeController specific settings.
+ * This is encoded as a key=value list, separated by commas. Ex:
+ *
+ * "skip_not_ready_jobs=true5,other_key=2"
+ *
+ * <p>
+ * Type: string
+ *
+ * @hide
+ * @see com.android.server.job.JobSchedulerService.Constants
+ */
+ public static final String JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS =
+ "job_scheduler_time_controller_constants";
+
+ /**
* ShortcutManager specific settings.
* This is encoded as a key=value list, separated by commas. Ex:
*
diff --git a/core/java/android/service/watchdog/ExplicitHealthCheckService.java b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
index eeefb4a..dc9c858 100644
--- a/core/java/android/service/watchdog/ExplicitHealthCheckService.java
+++ b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
@@ -183,7 +183,6 @@
*/
@SystemApi
public static final class PackageConfig implements Parcelable {
- // TODO: Receive from DeviceConfig flag
private static final long DEFAULT_HEALTH_CHECK_TIMEOUT_MILLIS = TimeUnit.HOURS.toMillis(1);
private final String mPackageName;
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c2aec6a..a25f2ee 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -508,14 +508,25 @@
*
* @param displayId Display ID.
* @param shouldShow Indicates that the display should show IME.
- * @see KeyguardManager#isDeviceSecure()
- * @see KeyguardManager#isDeviceLocked()
* @hide
*/
@TestApi
default void setShouldShowIme(int displayId, boolean shouldShow) {
}
+ /**
+ * Indicates that the display should show IME.
+ *
+ * @param displayId The id of the display.
+ * @return {@code true} if the display should show IME when an input field becomes
+ * focused on it.
+ * @hide
+ */
+ @TestApi
+ default boolean shouldShowIme(int displayId) {
+ return false;
+ }
+
public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
/**
* X position for this window. With the default gravity it is ignored.
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 2e4db5c..c349443 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -192,4 +192,13 @@
} catch (RemoteException e) {
}
}
+
+ @Override
+ public boolean shouldShowIme(int displayId) {
+ try {
+ return WindowManagerGlobal.getWindowManagerService().shouldShowIme(displayId);
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
}
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index 417c6e7..042b943 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -25,6 +25,7 @@
import android.database.ContentObserver;
import android.os.ServiceManager;
import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.Properties;
import android.provider.Settings;
import android.service.textclassifier.TextClassifierService;
import android.view.textclassifier.TextClassifier.TextClassifierType;
@@ -199,7 +200,7 @@
getApplicationContext().getContentResolver()
.unregisterContentObserver(mSettingsObserver);
if (ConfigParser.ENABLE_DEVICE_CONFIG) {
- DeviceConfig.removeOnPropertyChangedListener(mSettingsObserver);
+ DeviceConfig.removeOnPropertiesChangedListener(mSettingsObserver);
}
}
} finally {
@@ -286,7 +287,7 @@
}
private static final class SettingsObserver extends ContentObserver
- implements DeviceConfig.OnPropertyChangedListener {
+ implements DeviceConfig.OnPropertiesChangedListener {
private final WeakReference<TextClassificationManager> mTcm;
@@ -298,7 +299,7 @@
false /* notifyForDescendants */,
this);
if (ConfigParser.ENABLE_DEVICE_CONFIG) {
- DeviceConfig.addOnPropertyChangedListener(
+ DeviceConfig.addOnPropertiesChangedListener(
DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
ActivityThread.currentApplication().getMainExecutor(),
this);
@@ -311,7 +312,7 @@
}
@Override
- public void onPropertyChanged(String namespace, String name, String value) {
+ public void onPropertiesChanged(Properties properties) {
invalidateSettings();
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 8b510a4..1eabbd8 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -2586,6 +2586,20 @@
}
@Override
+ public boolean areAllItemsEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ int viewType = getItemViewType(position);
+ if (viewType == VIEW_TYPE_CONTENT_PREVIEW) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
public int getCount() {
return (int) (
getContentPreviewRowCount()
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index 76826d3..9e8bd64 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -45,6 +45,7 @@
import android.webkit.MimeTypeMap;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.ArrayUtils;
import libcore.io.IoUtils;
@@ -450,7 +451,11 @@
@Override
public String getDocumentType(String documentId) throws FileNotFoundException {
- final File file = getFileForDocId(documentId);
+ return getDocumentType(documentId, getFileForDocId(documentId));
+ }
+
+ private String getDocumentType(final String documentId, final File file)
+ throws FileNotFoundException {
if (file.isDirectory()) {
return Document.MIME_TYPE_DIR;
} else {
@@ -532,51 +537,63 @@
return DocumentsContract.openImageThumbnail(file);
}
- protected RowBuilder includeFile(MatrixCursor result, String docId, File file)
+ protected RowBuilder includeFile(final MatrixCursor result, String docId, File file)
throws FileNotFoundException {
+ final String[] columns = result.getColumnNames();
+ final RowBuilder row = result.newRow();
+
if (docId == null) {
docId = getDocIdForFile(file);
} else {
file = getFileForDocId(docId);
}
+ final String mimeType = getDocumentType(docId, file);
+ row.add(Document.COLUMN_DOCUMENT_ID, docId);
+ row.add(Document.COLUMN_MIME_TYPE, mimeType);
- int flags = 0;
+ final int flagIndex = ArrayUtils.indexOf(columns, Document.COLUMN_FLAGS);
+ if (flagIndex != -1) {
+ int flags = 0;
+ if (file.canWrite()) {
+ if (mimeType.equals(Document.MIME_TYPE_DIR)) {
+ flags |= Document.FLAG_DIR_SUPPORTS_CREATE;
+ flags |= Document.FLAG_SUPPORTS_DELETE;
+ flags |= Document.FLAG_SUPPORTS_RENAME;
+ flags |= Document.FLAG_SUPPORTS_MOVE;
+ } else {
+ flags |= Document.FLAG_SUPPORTS_WRITE;
+ flags |= Document.FLAG_SUPPORTS_DELETE;
+ flags |= Document.FLAG_SUPPORTS_RENAME;
+ flags |= Document.FLAG_SUPPORTS_MOVE;
+ }
+ }
- if (file.canWrite()) {
- if (file.isDirectory()) {
- flags |= Document.FLAG_DIR_SUPPORTS_CREATE;
- flags |= Document.FLAG_SUPPORTS_DELETE;
- flags |= Document.FLAG_SUPPORTS_RENAME;
- flags |= Document.FLAG_SUPPORTS_MOVE;
- } else {
- flags |= Document.FLAG_SUPPORTS_WRITE;
- flags |= Document.FLAG_SUPPORTS_DELETE;
- flags |= Document.FLAG_SUPPORTS_RENAME;
- flags |= Document.FLAG_SUPPORTS_MOVE;
+ if (mimeType.startsWith("image/")) {
+ flags |= Document.FLAG_SUPPORTS_THUMBNAIL;
+ }
+
+ if (typeSupportsMetadata(mimeType)) {
+ flags |= Document.FLAG_SUPPORTS_METADATA;
+ }
+ row.add(flagIndex, flags);
+ }
+
+ final int displayNameIndex = ArrayUtils.indexOf(columns, Document.COLUMN_DISPLAY_NAME);
+ if (displayNameIndex != -1) {
+ row.add(displayNameIndex, file.getName());
+ }
+
+ final int lastModifiedIndex = ArrayUtils.indexOf(columns, Document.COLUMN_LAST_MODIFIED);
+ if (lastModifiedIndex != -1) {
+ final long lastModified = file.lastModified();
+ // Only publish dates reasonably after epoch
+ if (lastModified > 31536000000L) {
+ row.add(lastModifiedIndex, lastModified);
}
}
-
- final String mimeType = getDocumentType(docId);
- final String displayName = file.getName();
- if (mimeType.startsWith("image/")) {
- flags |= Document.FLAG_SUPPORTS_THUMBNAIL;
- }
-
- if (typeSupportsMetadata(mimeType)) {
- flags |= Document.FLAG_SUPPORTS_METADATA;
- }
-
- final RowBuilder row = result.newRow();
- row.add(Document.COLUMN_DOCUMENT_ID, docId);
- row.add(Document.COLUMN_DISPLAY_NAME, displayName);
- row.add(Document.COLUMN_SIZE, file.length());
- row.add(Document.COLUMN_MIME_TYPE, mimeType);
- row.add(Document.COLUMN_FLAGS, flags);
-
- // Only publish dates reasonably after epoch
- long lastModified = file.lastModified();
- if (lastModified > 31536000000L) {
- row.add(Document.COLUMN_LAST_MODIFIED, lastModified);
+ final int sizeIndex = ArrayUtils.indexOf(columns, Document.COLUMN_SIZE);
+ if (sizeIndex != -1) {
+ row.add(sizeIndex, file.length());
}
// Return the row builder just in case any subclass want to add more stuff to it.
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 1ff7418..9cffb2b 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2354,4 +2354,11 @@
// OPEN: Settings > Pick preferred SIM dialog
DIALOG_PREFERRED_SIM_PICKER = 1709;
+
+ // OPEN: Settings > Network & internet > Mobile network > Delete sim
+ DIALOG_DELETE_SIM_CONFIRMATION = 1713;
+
+ // OPEN: Settings > Network & internet > Mobile network > Delete sim > (answer yes to
+ // confirmation)
+ DIALOG_DELETE_SIM_PROGRESS = 1714;
}
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index b47097d..8f16b41 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -501,7 +501,10 @@
}
optional IntentFirewall intent_firewall = 65;
- optional SettingProto job_scheduler_constants = 66;
+ optional SettingProto job_scheduler_constants = 66 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto job_scheduler_quota_controller_constants = 149 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto job_scheduler_time_controller_constants = 150 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
optional SettingProto keep_profile_in_background = 67 [ (android.privacy).dest = DEST_AUTOMATIC ];
message LangId {
@@ -1049,5 +1052,5 @@
// Please insert fields in alphabetical order and group them into messages
// if possible (to avoid reaching the method limit).
- // Next tag = 149;
+ // Next tag = 151;
}
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index 8727f4c..17b5f50 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -37,8 +37,8 @@
android:layout_width="24dp"
android:layout_height="4dp"
android:src="@drawable/ic_drag_handle"
- android:clickable="true"
android:layout_marginTop="@dimen/chooser_edge_margin_thin"
+ android:layout_marginBottom="@dimen/chooser_edge_margin_thin"
android:tint="@color/lighter_gray"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true" />
@@ -46,11 +46,8 @@
<TextView android:id="@+id/title"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:textAppearance="?attr/textAppearanceMedium"
- android:textSize="20sp"
- android:textColor="?attr/textColorPrimary"
+ android:textAppearance="@style/TextAppearance.DeviceDefault.WindowTitle"
android:gravity="center"
- android:paddingTop="@dimen/chooser_edge_margin_thin"
android:paddingBottom="@dimen/chooser_view_spacing"
android:paddingLeft="24dp"
android:paddingRight="24dp"
diff --git a/core/res/res/layout/chooser_grid_preview_text.xml b/core/res/res/layout/chooser_grid_preview_text.xml
index f3ca0af..e889e85 100644
--- a/core/res/res/layout/chooser_grid_preview_text.xml
+++ b/core/res/res/layout/chooser_grid_preview_text.xml
@@ -44,6 +44,7 @@
android:layout_toStartOf="@id/copy_button"
android:layout_centerVertical="true"
android:ellipsize="end"
+ android:fontFamily="@android:string/config_headlineFontFamily"
android:textColor="?android:attr/textColorPrimary"
android:maxLines="2"/>
@@ -112,8 +113,8 @@
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:maxLines="2"
- android:textSize="20sp"
- android:textColor="?android:attr/textColorPrimary"/>
+ android:textAppearance="@style/TextAppearance.DeviceDefault.WindowTitle"
+ android:fontFamily="@android:string/config_headlineFontFamily"/>
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout/chooser_profile_row.xml b/core/res/res/layout/chooser_profile_row.xml
index 1a24a07..fe4f949 100644
--- a/core/res/res/layout/chooser_profile_row.xml
+++ b/core/res/res/layout/chooser_profile_row.xml
@@ -20,7 +20,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
- <TextView
+ <Button
android:id="@+id/profile_button"
android:layout_width="wrap_content"
android:layout_height="48dp"
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index f4d3c81..61fb811 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -294,6 +294,8 @@
Settings.Global.INTENT_FIREWALL_UPDATE_CONTENT_URL,
Settings.Global.INTENT_FIREWALL_UPDATE_METADATA_URL,
Settings.Global.JOB_SCHEDULER_CONSTANTS,
+ Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS,
+ Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS,
Settings.Global.KEEP_PROFILE_IN_BACKGROUND,
Settings.Global.KERNEL_CPU_THREAD_READER,
Settings.Global.LANG_ID_UPDATE_CONTENT_URL,
diff --git a/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java b/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java
index 46288bb..296db46 100644
--- a/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java
+++ b/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java
@@ -102,10 +102,10 @@
}
private void registerDeviceConfigs() {
- DeviceConfig.addOnPropertyChangedListener(
+ DeviceConfig.addOnPropertiesChangedListener(
DeviceConfig.NAMESPACE_SYSTEMUI,
this::postToHandler,
- this::onDeviceConfigPropertyChanged);
+ (properties) -> onDeviceConfigPropertiesChanged(properties.getNamespace()));
// Update the fields in this class from the current state of the device config.
updateFromDeviceConfigFlags();
@@ -116,10 +116,10 @@
}
@VisibleForTesting
- void onDeviceConfigPropertyChanged(String namespace, String name, String value) {
+ void onDeviceConfigPropertiesChanged(String namespace) {
if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(namespace)) {
Log.e(LOG_TAG, "Received update from DeviceConfig for unrelated namespace: "
- + namespace + " " + name + "=" + value);
+ + namespace);
return;
}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java
index ad52e2b..5c877de 100644
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java
@@ -96,10 +96,7 @@
SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
"false",
false /* makeDefault */));
- mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
- "false");
+ mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
assertFalse(mAssistantSettings.mGenerateReplies);
}
@@ -111,10 +108,7 @@
SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
"true",
false /* makeDefault */));
- mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
- "true");
+ mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
assertTrue(mAssistantSettings.mGenerateReplies);
}
@@ -126,10 +120,7 @@
SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
"false",
false /* makeDefault */));
- mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
- "false");
+ mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
assertFalse(mAssistantSettings.mGenerateReplies);
@@ -138,10 +129,7 @@
SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
null,
false /* makeDefault */));
- mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
- null);
+ mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
// Go back to the default value.
assertTrue(mAssistantSettings.mGenerateReplies);
@@ -154,10 +142,7 @@
SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
"false",
false /* makeDefault */));
- mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
- "false");
+ mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
assertFalse(mAssistantSettings.mGenerateActions);
}
@@ -169,10 +154,7 @@
SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
"true",
false /* makeDefault */));
- mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
- "true");
+ mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
assertTrue(mAssistantSettings.mGenerateActions);
}
@@ -184,10 +166,7 @@
SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
"false",
false /* makeDefault */));
- mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
- "false");
+ mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
assertFalse(mAssistantSettings.mGenerateActions);
@@ -196,10 +175,7 @@
SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
null,
false /* makeDefault */));
- mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
- null);
+ mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
// Go back to the default value.
assertTrue(mAssistantSettings.mGenerateActions);
@@ -212,10 +188,7 @@
SystemUiDeviceConfigFlags.NAS_MAX_MESSAGES_TO_EXTRACT,
"10",
false /* makeDefault */));
- mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.NAS_MAX_MESSAGES_TO_EXTRACT,
- "10");
+ mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
assertEquals(10, mAssistantSettings.mMaxMessagesToExtract);
}
@@ -227,20 +200,14 @@
SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS,
"5",
false /* makeDefault */));
- mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS,
- "5");
+ mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
assertEquals(5, mAssistantSettings.mMaxSuggestions);
}
@Test
public void testMaxSuggestionsEmpty() {
- mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS,
- "");
+ mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
assertEquals(DEFAULT_MAX_SUGGESTIONS, mAssistantSettings.mMaxSuggestions);
}
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
index e0bb862..62de2ba 100644
--- a/packages/NetworkStack/Android.bp
+++ b/packages/NetworkStack/Android.bp
@@ -56,15 +56,24 @@
srcs: [
"jni/network_stack_utils_jni.cpp"
],
-
+ sdk_version: "current",
shared_libs: [
"liblog",
- "libcutils",
- "libnativehelper",
+ "libnativehelper_compat_libc++",
],
- static_libs: [
- "libpcap",
- ],
+
+ // We cannot use plain "libc++" here to link libc++ dynamically because it results in:
+ // java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found
+ // even if "libc++" is added into jni_libs below. Adding "libc++_shared" into jni_libs doesn't
+ // build because soong complains of:
+ // module NetworkStack missing dependencies: libc++_shared
+ //
+ // So, link libc++ statically. This means that we also need to ensure that all the C++ libraries
+ // we depend on do not dynamically link libc++. This is currently the case, because liblog is
+ // C-only and libnativehelper_compat_libc also uses stl: "c++_static".
+ //
+ // TODO: find a better solution for this in R.
+ stl: "c++_static",
cflags: [
"-Wall",
"-Werror",
@@ -79,7 +88,10 @@
static_libs: [
"NetworkStackBase",
],
- jni_libs: ["libnetworkstackutilsjni"],
+ jni_libs: [
+ "libnativehelper_compat_libc++",
+ "libnetworkstackutilsjni",
+ ],
// Resources already included in NetworkStackBase
resource_dirs: [],
jarjar_rules: "jarjar-rules-shared.txt",
diff --git a/packages/NetworkStack/jni/network_stack_utils_jni.cpp b/packages/NetworkStack/jni/network_stack_utils_jni.cpp
index 5544eaa..f2ba575 100644
--- a/packages/NetworkStack/jni/network_stack_utils_jni.cpp
+++ b/packages/NetworkStack/jni/network_stack_utils_jni.cpp
@@ -31,7 +31,7 @@
#include <string>
#include <nativehelper/JNIHelp.h>
-#include <utils/Log.h>
+#include <android/log.h>
namespace android {
constexpr const char NETWORKSTACKUTILS_PKG_NAME[] = "android/net/util/NetworkStackUtils";
@@ -249,7 +249,7 @@
extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
- ALOGE("ERROR: GetEnv failed");
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
return JNI_ERR;
}
@@ -261,4 +261,4 @@
return JNI_VERSION_1_6;
}
-}; // namespace android
\ No newline at end of file
+}; // namespace android
diff --git a/packages/NetworkStack/tests/Android.bp b/packages/NetworkStack/tests/Android.bp
index fe3c1e8..039f6bf 100644
--- a/packages/NetworkStack/tests/Android.bp
+++ b/packages/NetworkStack/tests/Android.bp
@@ -56,6 +56,7 @@
"liblog",
"liblzma",
"libnativehelper",
+ "libnativehelper_compat_libc++",
"libnetworkstacktestsjni",
"libnetworkstackutilsjni",
"libpackagelistparser",
@@ -99,5 +100,4 @@
"libapf",
"libpcap",
],
-
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index cd4f6cf..c94ee0e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -797,6 +797,12 @@
Settings.Global.JOB_SCHEDULER_CONSTANTS,
GlobalSettingsProto.JOB_SCHEDULER_CONSTANTS);
dumpSetting(s, p,
+ Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS,
+ GlobalSettingsProto.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS);
+ dumpSetting(s, p,
+ Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS,
+ GlobalSettingsProto.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS);
+ dumpSetting(s, p,
Settings.Global.KEEP_PROFILE_IN_BACKGROUND,
GlobalSettingsProto.KEEP_PROFILE_IN_BACKGROUND);
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
index 66d5d11..25a3fa2 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
@@ -17,6 +17,7 @@
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.Intent;
+import android.view.View;
import com.android.systemui.plugins.annotations.ProvidesInterface;
@@ -32,13 +33,20 @@
void startPendingIntentDismissingKeyguard(PendingIntent intent);
/**
- * Similar to {@link #startPendingIntentDismissingKeyguard(PendingIntent, Runnable)}, but allows
+ * Similar to {@link #startPendingIntentDismissingKeyguard(PendingIntent)}, but allows
* you to specify the callback that is executed on the UI thread after the intent is sent.
*/
void startPendingIntentDismissingKeyguard(PendingIntent intent,
Runnable intentSentUiThreadCallback);
/**
+ * Similar to {@link #startPendingIntentDismissingKeyguard(PendingIntent, Runnable)}, but also
+ * specifies an associated view that should be used for the activity launch animation.
+ */
+ void startPendingIntentDismissingKeyguard(PendingIntent intent,
+ Runnable intentSentUiThreadCallback, View associatedView);
+
+ /**
* The intent flag can be specified in startActivity().
*/
void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade, int flags);
diff --git a/packages/SystemUI/res/layout/qs_carrier.xml b/packages/SystemUI/res/layout/qs_carrier.xml
index 8f74806..8dd06f0 100644
--- a/packages/SystemUI/res/layout/qs_carrier.xml
+++ b/packages/SystemUI/res/layout/qs_carrier.xml
@@ -42,6 +42,7 @@
android:layout_weight="1"
android:textAppearance="@style/TextAppearance.QS.Status"
android:textDirection="locale"
+ android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:maxEms="7"/>
diff --git a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
index 04f887b..41a7bc4 100644
--- a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
@@ -16,6 +16,7 @@
import android.app.PendingIntent;
import android.content.Intent;
+import android.view.View;
import com.android.systemui.plugins.ActivityStarter;
@@ -53,6 +54,16 @@
}
@Override
+ public void startPendingIntentDismissingKeyguard(PendingIntent intent,
+ Runnable intentSentCallback, View associatedView) {
+ if (mActualStarter == null) {
+ return;
+ }
+ mActualStarter.startPendingIntentDismissingKeyguard(intent, intentSentCallback,
+ associatedView);
+ }
+
+ @Override
public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade,
int flags) {
if (mActualStarter == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index fa22367..1615e65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -39,6 +39,7 @@
import android.os.Trace;
import android.os.UserHandle;
import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.Properties;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
@@ -118,15 +119,18 @@
private ImageView mBackdropBack;
private boolean mShowCompactMediaSeekbar;
- private final DeviceConfig.OnPropertyChangedListener mPropertyChangedListener =
- new DeviceConfig.OnPropertyChangedListener() {
+ private final DeviceConfig.OnPropertiesChangedListener mPropertiesChangedListener =
+ new DeviceConfig.OnPropertiesChangedListener() {
@Override
- public void onPropertyChanged(String namespace, String name, String value) {
- if (SystemUiDeviceConfigFlags.COMPACT_MEDIA_SEEKBAR_ENABLED.equals(name)) {
- if (DEBUG_MEDIA) {
- Log.v(TAG, "DEBUG_MEDIA: compact media seekbar flag updated: " + value);
+ public void onPropertiesChanged(Properties properties) {
+ for (String name : properties.getKeyset()) {
+ if (SystemUiDeviceConfigFlags.COMPACT_MEDIA_SEEKBAR_ENABLED.equals(name)) {
+ String value = properties.getString(name, null);
+ if (DEBUG_MEDIA) {
+ Log.v(TAG, "DEBUG_MEDIA: compact media seekbar flag updated: " + value);
+ }
+ mShowCompactMediaSeekbar = "true".equals(value);
}
- mShowCompactMediaSeekbar = "true".equals(value);
}
}
};
@@ -189,9 +193,9 @@
DeviceConfig.getProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.COMPACT_MEDIA_SEEKBAR_ENABLED));
- DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
+ DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
mContext.getMainExecutor(),
- mPropertyChangedListener);
+ mPropertiesChangedListener);
}
public void setUpWithPresenter(NotificationPresenter presenter) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index 333239e..0d9f4e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -30,6 +30,7 @@
import android.view.RemoteAnimationTarget;
import android.view.SyncRtSurfaceTransactionApplier;
import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
+import android.view.View;
import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.systemui.Interpolators;
@@ -79,11 +80,12 @@
}
public RemoteAnimationAdapter getLaunchAnimation(
- ExpandableNotificationRow sourceNotification, boolean occluded) {
- if (!mCallback.areLaunchAnimationsEnabled() || occluded) {
+ View sourceView, boolean occluded) {
+ if (!(sourceView instanceof ExpandableNotificationRow) || !mCallback.areLaunchAnimationsEnabled() || occluded) {
return null;
}
- AnimationRunner animationRunner = new AnimationRunner(sourceNotification);
+ AnimationRunner animationRunner = new AnimationRunner(
+ (ExpandableNotificationRow) sourceView);
return new RemoteAnimationAdapter(animationRunner, ANIMATION_DURATION,
ANIMATION_DURATION - 150 /* statusBarTransitionDelay */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index ef7d20c..73f7732 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -42,7 +42,6 @@
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.AlphaOptimizedImageView;
-import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.row.NotificationGuts.GutsContent;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
@@ -80,7 +79,7 @@
private OnMenuEventListener mMenuListener;
private boolean mDismissRtl;
private boolean mIsForeground;
- private final boolean mIsUsingNewInterruptionModel;
+ private final boolean mIsUsingBidirectionalSwipe;
private ValueAnimator mFadeAnimator;
private boolean mAnimating;
@@ -113,12 +112,19 @@
private boolean mIsUserTouching;
public NotificationMenuRow(Context context) {
+ //TODO: (b/131242807) not using bidirectional swipe for now
+ this(context, false);
+ }
+
+ // Only needed for testing until we want to turn bidirectional swipe back on
+ @VisibleForTesting
+ NotificationMenuRow(Context context, boolean isUsingBidirectionalSwipe) {
mContext = context;
mShouldShowMenu = context.getResources().getBoolean(R.bool.config_showNotificationGear);
mHandler = new Handler(Looper.getMainLooper());
mLeftMenuItems = new ArrayList<>();
mRightMenuItems = new ArrayList<>();
- mIsUsingNewInterruptionModel = NotificationUtils.useNewInterruptionModel(mContext);
+ mIsUsingBidirectionalSwipe = isUsingBidirectionalSwipe;
}
@Override
@@ -255,13 +261,13 @@
mSnoozeItem = createSnoozeItem(mContext);
}
mAppOpsItem = createAppOpsItem(mContext);
- if (mIsUsingNewInterruptionModel) {
+ if (mIsUsingBidirectionalSwipe) {
mInfoItem = createInfoItem(mContext, !mParent.getEntry().isHighPriority());
} else {
mInfoItem = createInfoItem(mContext);
}
- if (!mIsUsingNewInterruptionModel) {
+ if (!mIsUsingBidirectionalSwipe) {
if (!isForeground) {
mRightMenuItems.add(mSnoozeItem);
}
@@ -618,12 +624,12 @@
@Override
public boolean shouldShowGutsOnSnapOpen() {
- return mIsUsingNewInterruptionModel;
+ return mIsUsingBidirectionalSwipe;
}
@Override
public MenuItem menuItemToExposeOnSnap() {
- return mIsUsingNewInterruptionModel ? mInfoItem : null;
+ return mIsUsingBidirectionalSwipe ? mInfoItem : null;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index ebda585..7a9da6b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -6355,13 +6355,8 @@
@Override
public boolean canChildBeDismissedInDirection(View v, boolean isRightOrDown) {
- boolean isValidDirection;
- if (NotificationUtils.useNewInterruptionModel(mContext)) {
- isValidDirection = mDismissRtl ? !isRightOrDown : isRightOrDown;
- } else {
- isValidDirection = true;
- }
- return isValidDirection && canChildBeDismissed(v);
+ //TODO: b/131242807 for why this doesn't do anything with direction
+ return canChildBeDismissed(v);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index d5706e3..27368de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -44,6 +44,7 @@
import com.android.systemui.UiOffloadThread;
import com.android.systemui.privacy.PrivacyItem;
import com.android.systemui.privacy.PrivacyItemController;
+import com.android.systemui.privacy.PrivacyType;
import com.android.systemui.qs.tiles.DndTile;
import com.android.systemui.qs.tiles.RotationLockTile;
import com.android.systemui.statusbar.CommandQueue;
@@ -229,9 +230,11 @@
mIconController.setIconVisibility(mSlotDataSaver, false);
// privacy items
- mIconController.setIcon(mSlotMicrophone, R.drawable.stat_sys_mic_none, null);
+ mIconController.setIcon(mSlotMicrophone, R.drawable.stat_sys_mic_none,
+ PrivacyType.TYPE_MICROPHONE.getName(mContext));
mIconController.setIconVisibility(mSlotMicrophone, false);
- mIconController.setIcon(mSlotCamera, R.drawable.stat_sys_camera, null);
+ mIconController.setIcon(mSlotCamera, R.drawable.stat_sys_camera,
+ PrivacyType.TYPE_CAMERA.getName(mContext));
mIconController.setIconVisibility(mSlotCamera, false);
mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID,
mContext.getString(R.string.accessibility_location_active));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 93db82d..739343a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -593,6 +593,7 @@
updateScrimController();
};
private ActivityIntentHelper mActivityIntentHelper;
+ private ShadeController mShadeController;
@Override
public void onActiveStateChanged(int code, int uid, String packageName, boolean active) {
@@ -1062,7 +1063,7 @@
final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback =
(StatusBarRemoteInputCallback) Dependency.get(
NotificationRemoteInputManager.Callback.class);
- final ShadeController shadeController = Dependency.get(ShadeController.class);
+ mShadeController = Dependency.get(ShadeController.class);
final ActivityStarter activityStarter = Dependency.get(ActivityStarter.class);
mNotificationActivityStarter = new StatusBarNotificationActivityStarter(mContext,
@@ -1070,7 +1071,7 @@
mHeadsUpManager, activityStarter, mActivityLaunchAnimator,
mBarService, mStatusBarStateController, mKeyguardManager, mDreamManager,
mRemoteInputManager, mStatusBarRemoteInputCallback, mGroupManager,
- mLockscreenUserManager, shadeController, mKeyguardMonitor,
+ mLockscreenUserManager, mShadeController, mKeyguardMonitor,
mNotificationInterruptionStateProvider, mMetricsLogger,
new LockPatternUtils(mContext), Dependency.get(MAIN_HANDLER),
Dependency.get(BG_HANDLER), mActivityIntentHelper, mBubbleController);
@@ -4344,6 +4345,13 @@
@Override
public void startPendingIntentDismissingKeyguard(
final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback) {
+ startPendingIntentDismissingKeyguard(intent, intentSentUiThreadCallback, null /* row */);
+ }
+
+ @Override
+ public void startPendingIntentDismissingKeyguard(
+ final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback,
+ View associatedView) {
final boolean afterKeyguardGone = intent.isActivity()
&& mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
mLockscreenUserManager.getCurrentUserId());
@@ -4351,7 +4359,8 @@
executeActionDismissingKeyguard(() -> {
try {
intent.send(null, 0, null, null, null, null, getActivityOptions(
- null /* animationAdapter */));
+ mActivityLaunchAnimator.getLaunchAnimation(associatedView,
+ mShadeController.isOccluded())));
} catch (PendingIntent.CanceledException e) {
// the stack trace isn't very helpful here.
// Just log the exception message.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java
index f02b544..655c29c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java
@@ -93,10 +93,10 @@
}
private void registerDeviceConfigListener() {
- DeviceConfig.addOnPropertyChangedListener(
+ DeviceConfig.addOnPropertiesChangedListener(
DeviceConfig.NAMESPACE_SYSTEMUI,
this::postToHandler,
- this::onDeviceConfigPropertyChanged);
+ (properties) -> onDeviceConfigPropertiesChanged(properties.getNamespace()));
}
private void postToHandler(Runnable r) {
@@ -104,10 +104,10 @@
}
@VisibleForTesting
- void onDeviceConfigPropertyChanged(String namespace, String name, String value) {
+ void onDeviceConfigPropertiesChanged(String namespace) {
if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(namespace)) {
Log.e(TAG, "Received update from DeviceConfig for unrelated namespace: "
- + namespace + " " + name + "=" + value);
+ + namespace);
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index 0f7a0f0..640f0f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -349,7 +349,7 @@
smartReplyController.smartActionClicked(
entry, actionIndex, action, smartActions.fromAssistant);
headsUpManager.removeNotification(entry.key, true);
- });
+ }, entry.getRow());
if (useDelayedOnClickListener) {
onClickListener = new DelayedOnClickListener(onClickListener,
smartReplyView.mConstants.getOnClickInitDelay());
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
index 212c8f5..e312990 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
@@ -189,10 +189,6 @@
when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY);
when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
- // STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the
- // same answer as KeyguardUpdateMonitor. Remove when this is addressed
- when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(list);
-
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
@@ -217,10 +213,6 @@
when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY);
when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
- // STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the
- // same answer as KeyguardUpdateMonitor. Remove when this is addressed
- when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(list);
-
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
@@ -243,11 +235,6 @@
when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(
new ArrayList<>());
- // STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the
- // same answer as KeyguardUpdateMonitor. Remove when this is addressed
- when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(
- new ArrayList<>());
-
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
CarrierTextController.CarrierTextCallbackInfo.class);
@@ -271,10 +258,6 @@
when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY);
when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
- // STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the
- // same answer as KeyguardUpdateMonitor. Remove when this is addressed
- when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(list);
-
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
@@ -300,10 +283,6 @@
.thenReturn(IccCardConstants.State.NOT_READY);
when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
- // STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the
- // same answer as KeyguardUpdateMonitor. Remove when this is addressed
- when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(list);
-
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
@@ -329,10 +308,6 @@
.thenReturn(IccCardConstants.State.READY);
when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
- // STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the
- // same answer as KeyguardUpdateMonitor. Remove when this is addressed
- when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(list);
-
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
@@ -361,10 +336,6 @@
when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
- // STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the
- // same answer as KeyguardUpdateMonitor. Remove when this is addressed
- when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(list);
-
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
CarrierTextController.CarrierTextCallbackInfo.class);
@@ -385,12 +356,9 @@
list.add(TEST_SUBSCRIPTION_2);
when(mKeyguardUpdateMonitor.getSimState(anyInt()))
.thenReturn(IccCardConstants.State.READY);
- when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
+
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
mCarrierTextController.updateDisplayOpportunisticSubscriptionCarrierText();
-
- // STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the
- // same answer as KeyguardUpdateMonitor. Remove when this is addressed
when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(list);
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
index c62a802..43ea92f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
@@ -112,11 +112,8 @@
}
@Test
- public void testNoAppOpsInSlowSwipe_newInterruptionModel() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
-
- NotificationMenuRow row = new NotificationMenuRow(mContext);
+ public void testNoAppOpsInSlowSwipe_biDirectionalSwipe() {
+ NotificationMenuRow row = new NotificationMenuRow(mContext, true);
row.createMenu(mRow, null);
ViewGroup container = (ViewGroup) row.getMenuView();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
index fb2b7dc..c761a44 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
@@ -229,8 +229,7 @@
}
private void triggerConstantsOnChange() {
- mConstants.onDeviceConfigPropertyChanged(DeviceConfig.NAMESPACE_SYSTEMUI,
- "" /* name */, "" /* value */);
+ mConstants.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
}
private void resetAllDeviceConfigFlags() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index 01f3c92..8c5fac4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -634,7 +634,8 @@
mView.getChildAt(2).performClick();
- verify(mActivityStarter, times(1)).startPendingIntentDismissingKeyguard(any(), any());
+ verify(mActivityStarter, times(1)).startPendingIntentDismissingKeyguard(any(), any(),
+ any());
}
@Test
@@ -645,7 +646,7 @@
mView.getChildAt(2).performClick();
- verify(mActivityStarter, never()).startPendingIntentDismissingKeyguard(any(), any());
+ verify(mActivityStarter, never()).startPendingIntentDismissingKeyguard(any(), any(), any());
}
@Test
@@ -657,7 +658,8 @@
Thread.sleep(delayMs);
mView.getChildAt(2).performClick();
- verify(mActivityStarter, times(1)).startPendingIntentDismissingKeyguard(any(), any());
+ verify(mActivityStarter, times(1)).startPendingIntentDismissingKeyguard(any(), any(),
+ any());
}
@Test
@@ -668,7 +670,8 @@
mView.getChildAt(2).performClick();
- verify(mActivityStarter, times(1)).startPendingIntentDismissingKeyguard(any(), any());
+ verify(mActivityStarter, times(1)).startPendingIntentDismissingKeyguard(any(), any(),
+ any());
}
@Test
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 21c6035..fe92d45 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -7206,6 +7206,13 @@
// ACTION: Share Wi-Fi hotspot by generating a QR code
ACTION_SETTINGS_SHARE_WIFI_HOTSPOT_QR_CODE = 1712;
+ // OPEN: Settings > Network & internet > Mobile network > Delete sim
+ DIALOG_DELETE_SIM_CONFIRMATION = 1713;
+
+ // OPEN: Settings > Network & internet > Mobile network > Delete sim > (answer yes to
+ // confirmation)
+ DIALOG_DELETE_SIM_PROGRESS = 1714;
+
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index a94d1dc..a64f4e4 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -94,6 +94,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
/**
* Entry point service for autofill management.
@@ -192,9 +193,9 @@
mUi = new AutoFillUI(ActivityThread.currentActivityThread().getSystemUiContext());
mAm = LocalServices.getService(ActivityManagerInternal.class);
- DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_AUTOFILL,
+ DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_AUTOFILL,
ActivityThread.currentApplication().getMainExecutor(),
- (namespace, key, value) -> onDeviceConfigChange(key));
+ (properties) -> onDeviceConfigChange(properties.getKeyset()));
setLogLevelFromSettings();
setMaxPartitionsFromSettings();
@@ -270,15 +271,17 @@
}
}
- private void onDeviceConfigChange(@NonNull String key) {
- switch (key) {
- case AutofillManager.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES:
- case AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT:
- case AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT:
- setDeviceConfigProperties();
- break;
- default:
- Slog.i(mTag, "Ignoring change on " + key);
+ private void onDeviceConfigChange(@NonNull Set<String> keys) {
+ for (String key : keys) {
+ switch (key) {
+ case AutofillManager.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES:
+ case AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT:
+ case AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT:
+ setDeviceConfigProperties();
+ break;
+ default:
+ Slog.i(mTag, "Ignoring change on " + key);
+ }
}
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index f1963b3..386dec4 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -57,6 +57,7 @@
import android.service.autofill.FillEventHistory.Event;
import android.service.autofill.FillResponse;
import android.service.autofill.IAutoFillService;
+import android.service.autofill.SaveInfo;
import android.service.autofill.UserData;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -595,8 +596,8 @@
ArrayList<Session> previousSessions = null;
for (int i = 0; i < size; i++) {
final Session previousSession = mSessions.valueAt(i);
- // TODO(b/113281366): only return sessions asked to be kept alive / add CTS test
- if (previousSession.taskId == session.taskId && previousSession.id != session.id) {
+ if (previousSession.taskId == session.taskId && previousSession.id != session.id
+ && (previousSession.getSaveInfoFlagsLocked() & SaveInfo.FLAG_DELAY_SAVE) != 0) {
if (previousSessions == null) {
previousSessions = new ArrayList<>(size);
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 9eda9db..7b97353 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -1203,9 +1203,12 @@
@GuardedBy("mLock")
@Nullable
- private FillResponse getLastResponseLocked(@Nullable String logPrefix) {
+ private FillResponse getLastResponseLocked(@Nullable String logPrefixFmt) {
+ final String logPrefix = sDebug && logPrefixFmt != null
+ ? String.format(logPrefixFmt, this.id)
+ : null;
if (mContexts == null) {
- if (sDebug && logPrefix != null) Slog.d(TAG, logPrefix + ": no contexts");
+ if (logPrefix != null) Slog.d(TAG, logPrefix + ": no contexts");
return null;
}
if (mResponses == null) {
@@ -1241,6 +1244,12 @@
return response == null ? null : response.getSaveInfo();
}
+ @GuardedBy("mLock")
+ int getSaveInfoFlagsLocked() {
+ final SaveInfo saveInfo = getSaveInfoLocked();
+ return saveInfo == null ? 0 : saveInfo.getFlags();
+ }
+
/**
* Generates a {@link android.service.autofill.FillEventHistory.Event#TYPE_CONTEXT_COMMITTED}
* when necessary.
@@ -1252,7 +1261,7 @@
private void handleLogContextCommitted() {
final FillResponse lastResponse;
synchronized (mLock) {
- lastResponse = getLastResponseLocked("logContextCommited()");
+ lastResponse = getLastResponseLocked("logContextCommited(%s)");
}
if (lastResponse == null) {
@@ -1295,7 +1304,7 @@
@GuardedBy("mLock")
private void logContextCommittedLocked(@Nullable ArrayList<AutofillId> detectedFieldIds,
@Nullable ArrayList<FieldClassification> detectedFieldClassifications) {
- final FillResponse lastResponse = getLastResponseLocked("logContextCommited()");
+ final FillResponse lastResponse = getLastResponseLocked("logContextCommited(%s)");
if (lastResponse == null) return;
final int flags = lastResponse.getFlags();
@@ -1610,7 +1619,7 @@
+ id + " destroyed");
return false;
}
- final FillResponse response = getLastResponseLocked("showSaveLocked()");
+ final FillResponse response = getLastResponseLocked("showSaveLocked(%s)");
final SaveInfo saveInfo = response == null ? null : response.getSaveInfo();
/*
@@ -1624,13 +1633,13 @@
* - server didn't ask to keep session alive
*/
if (saveInfo == null) {
- if (sVerbose) Slog.v(TAG, "showSaveLocked(): no saveInfo from service");
+ if (sVerbose) Slog.v(TAG, "showSaveLocked(" + this.id + "): no saveInfo from service");
return true;
}
if ((saveInfo.getFlags() & SaveInfo.FLAG_DELAY_SAVE) != 0) {
// TODO(b/113281366): log metrics
- if (sDebug) Slog.v(TAG, "showSaveLocked(): service asked to delay save");
+ if (sDebug) Slog.v(TAG, "showSaveLocked(" + this.id + "): service asked to delay save");
return false;
}
@@ -1962,7 +1971,8 @@
if (node != null) {
final AutofillValue value = node.getAutofillValue();
if (sDebug) {
- Slog.d(TAG, "getValueFromContexts(" + autofillId + ") at " + i + ": " + value);
+ Slog.d(TAG, "getValueFromContexts(" + this.id + "/" + autofillId + ") at "
+ + i + ": " + value);
}
if (value != null && !value.isEmpty()) {
return value;
@@ -2066,7 +2076,7 @@
return;
}
- if (sVerbose) Slog.v(TAG, "callSaveLocked(): mViewStates=" + mViewStates);
+ if (sVerbose) Slog.v(TAG, "callSaveLocked(" + this.id + "): mViewStates=" + mViewStates);
if (mContexts == null) {
Slog.w(TAG, "callSaveLocked(): no contexts");
@@ -2109,15 +2119,15 @@
final ArrayList<FillContext> contexts;
if (previousSessions != null) {
if (sDebug) {
- Slog.d(TAG, "mergeSessions(): Merging the content of " + previousSessions.size()
- + " sessions for task " + taskId);
+ Slog.d(TAG, "mergeSessions(" + this.id + "): Merging the content of "
+ + previousSessions.size() + " sessions for task " + taskId);
}
contexts = new ArrayList<>();
for (int i = 0; i < previousSessions.size(); i++) {
final Session previousSession = previousSessions.get(i);
final ArrayList<FillContext> previousContexts = previousSession.mContexts;
if (previousContexts == null) {
- Slog.w(TAG, "mergeSessions(): Not merging null contexts from "
+ Slog.w(TAG, "mergeSessions(" + this.id + "): Not merging null contexts from "
+ previousSession.id);
continue;
}
@@ -2125,14 +2135,14 @@
previousSession.updateValuesForSaveLocked();
}
if (sDebug) {
- Slog.d(TAG, "mergeSessions(): adding " + previousContexts.size()
+ Slog.d(TAG, "mergeSessions(" + this.id + "): adding " + previousContexts.size()
+ " context from previous session #" + previousSession.id);
}
contexts.addAll(previousContexts);
if (mClientState == null && previousSession.mClientState != null) {
if (sDebug) {
- Slog.d(TAG, "mergeSessions(): setting client state from previous session"
- + previousSession.id);
+ Slog.d(TAG, "mergeSessions(" + this.id + "): setting client state from "
+ + "previous session" + previousSession.id);
}
mClientState = previousSession.mClientState;
}
@@ -2250,8 +2260,8 @@
return;
}
if (sVerbose) {
- Slog.v(TAG, "updateLocked(): id=" + id + ", action=" + actionAsString(action)
- + ", flags=" + flags);
+ Slog.v(TAG, "updateLocked(" + this.id + "): id=" + id + ", action="
+ + actionAsString(action) + ", flags=" + flags);
}
ViewState viewState = mViewStates.get(id);
@@ -3291,7 +3301,7 @@
*/
@GuardedBy("mLock")
void removeSelfLocked() {
- if (sVerbose) Slog.v(TAG, "removeSelfLocked(): " + mPendingSaveUi);
+ if (sVerbose) Slog.v(TAG, "removeSelfLocked(" + this.id + "): " + mPendingSaveUi);
if (mDestroyed) {
Slog.w(TAG, "Call to Session#removeSelfLocked() rejected - session: "
+ id + " destroyed");
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index 33a2e50..e1b089c 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -214,7 +214,7 @@
if (mDatasetId != null) {
builder.append(", datasetId:" ).append(mDatasetId);
}
- builder.append("state:" ).append(getStateAsString());
+ builder.append(", state:").append(getStateAsString());
if (mCurrentValue != null) {
builder.append(", currentValue:" ).append(mCurrentValue);
}
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index a2d3d4c..5c6258f 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -50,6 +50,7 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.Properties;
import android.provider.Settings;
import android.service.contentcapture.ActivityEvent.ActivityEventType;
import android.util.ArraySet;
@@ -131,9 +132,9 @@
com.android.internal.R.string.config_defaultContentCaptureService),
UserManager.DISALLOW_CONTENT_CAPTURE,
/*packageUpdatePolicy=*/ PACKAGE_UPDATE_POLICY_NO_REFRESH);
- DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
ActivityThread.currentApplication().getMainExecutor(),
- (namespace, key, value) -> onDeviceConfigChange(key, value));
+ (properties) -> onDeviceConfigChange(properties));
setDeviceConfigProperties();
if (mDevCfgLogHistorySize > 0) {
@@ -255,23 +256,25 @@
return enabled;
}
- private void onDeviceConfigChange(@NonNull String key, @Nullable String value) {
- switch (key) {
- case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED:
- setDisabledByDeviceConfig(value);
- return;
- case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_LOGGING_LEVEL:
- setLoggingLevelFromDeviceConfig();
- return;
- case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_MAX_BUFFER_SIZE:
- case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_IDLE_FLUSH_FREQUENCY:
- case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_LOG_HISTORY_SIZE:
- case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_TEXT_CHANGE_FLUSH_FREQUENCY:
- case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_IDLE_UNBIND_TIMEOUT:
- setFineTuneParamsFromDeviceConfig();
- return;
- default:
- Slog.i(mTag, "Ignoring change on " + key);
+ private void onDeviceConfigChange(@NonNull Properties properties) {
+ for (String key : properties.getKeyset()) {
+ switch (key) {
+ case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED:
+ setDisabledByDeviceConfig(properties.getString(key, null));
+ return;
+ case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_LOGGING_LEVEL:
+ setLoggingLevelFromDeviceConfig();
+ return;
+ case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_MAX_BUFFER_SIZE:
+ case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_IDLE_FLUSH_FREQUENCY:
+ case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_LOG_HISTORY_SIZE:
+ case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_TEXT_CHANGE_FLUSH_FREQUENCY:
+ case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_IDLE_UNBIND_TIMEOUT:
+ setFineTuneParamsFromDeviceConfig();
+ return;
+ default:
+ Slog.i(mTag, "Ignoring change on " + key);
+ }
}
}
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index b44009f..7b5b419 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -29,6 +29,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
+import android.provider.DeviceConfig;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -61,6 +62,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
/**
* Monitors the health of packages on the system and notifies interested observers when packages
@@ -69,10 +71,22 @@
*/
public class PackageWatchdog {
private static final String TAG = "PackageWatchdog";
+
+ static final String PROPERTY_WATCHDOG_TRIGGER_DURATION_MILLIS =
+ "watchdog_trigger_failure_duration_millis";
+ static final String PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT =
+ "watchdog_trigger_failure_count";
+ static final String PROPERTY_WATCHDOG_EXPLICIT_HEALTH_CHECK_ENABLED =
+ "watchdog_explicit_health_check_enabled";
+
// Duration to count package failures before it resets to 0
- private static final int TRIGGER_DURATION_MS = 60000;
+ private static final int DEFAULT_TRIGGER_FAILURE_DURATION_MS =
+ (int) TimeUnit.MINUTES.toMillis(1);
// Number of package failures within the duration above before we notify observers
- static final int TRIGGER_FAILURE_COUNT = 5;
+ private static final int DEFAULT_TRIGGER_FAILURE_COUNT = 5;
+ // Whether explicit health checks are enabled or not
+ private static final boolean DEFAULT_EXPLICIT_HEALTH_CHECK_ENABLED = true;
+
private static final int DB_VERSION = 1;
private static final String TAG_PACKAGE_WATCHDOG = "package-watchdog";
private static final String TAG_PACKAGE = "package";
@@ -83,6 +97,7 @@
private static final String ATTR_EXPLICIT_HEALTH_CHECK_DURATION = "health-check-duration";
private static final String ATTR_PASSED_HEALTH_CHECK = "passed-health-check";
+ @GuardedBy("PackageWatchdog.class")
private static PackageWatchdog sPackageWatchdog;
private final Object mLock = new Object();
@@ -100,11 +115,15 @@
// File containing the XML data of monitored packages /data/system/package-watchdog.xml
private final AtomicFile mPolicyFile;
private final ExplicitHealthCheckController mHealthCheckController;
- // Flag to control whether explicit health checks are supported or not
- @GuardedBy("mLock")
- private boolean mIsHealthCheckEnabled = true;
@GuardedBy("mLock")
private boolean mIsPackagesReady;
+ // Flag to control whether explicit health checks are supported or not
+ @GuardedBy("mLock")
+ private boolean mIsHealthCheckEnabled = DEFAULT_EXPLICIT_HEALTH_CHECK_ENABLED;
+ @GuardedBy("mLock")
+ private int mTriggerFailureDurationMs = DEFAULT_TRIGGER_FAILURE_DURATION_MS;
+ @GuardedBy("mLock")
+ private int mTriggerFailureCount = DEFAULT_TRIGGER_FAILURE_COUNT;
// SystemClock#uptimeMillis when we last executed #syncState
// 0 if no prune is scheduled.
@GuardedBy("mLock")
@@ -153,8 +172,8 @@
mHealthCheckController.setCallbacks(packageName -> onHealthCheckPassed(packageName),
packages -> onSupportedPackages(packages),
() -> syncRequestsAsync());
- // Controller is initially disabled until here where we may enable it and sync our state
- setExplicitHealthCheckEnabled(mIsHealthCheckEnabled);
+ setPropertyChangedListenerLocked();
+ updateConfigs();
}
}
@@ -332,14 +351,13 @@
}
}
- // TODO(b/120598832): Set depending on DeviceConfig flag
/**
* Enables or disables explicit health checks.
* <p> If explicit health checks are enabled, the health check service is started.
* <p> If explicit health checks are disabled, pending explicit health check requests are
* passed and the health check service is stopped.
*/
- public void setExplicitHealthCheckEnabled(boolean enabled) {
+ private void setExplicitHealthCheckEnabled(boolean enabled) {
synchronized (mLock) {
mIsHealthCheckEnabled = enabled;
mHealthCheckController.setEnabled(enabled);
@@ -390,6 +408,12 @@
String getName();
}
+ long getTriggerFailureCount() {
+ synchronized (mLock) {
+ return mTriggerFailureCount;
+ }
+ }
+
/**
* Serializes and syncs health check requests with the {@link ExplicitHealthCheckController}.
*/
@@ -646,7 +670,7 @@
XmlUtils.beginDocument(parser, TAG_PACKAGE_WATCHDOG);
int outerDepth = parser.getDepth();
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
- ObserverInternal observer = ObserverInternal.read(parser);
+ ObserverInternal observer = ObserverInternal.read(parser, this);
if (observer != null) {
mAllObservers.put(observer.mName, observer);
}
@@ -661,6 +685,48 @@
}
}
+ /** Adds a {@link DeviceConfig#OnPropertyChangedListener}. */
+ private void setPropertyChangedListenerLocked() {
+ DeviceConfig.addOnPropertyChangedListener(
+ DeviceConfig.NAMESPACE_ROLLBACK,
+ mContext.getMainExecutor(),
+ (namespace, name, value) -> {
+ if (!DeviceConfig.NAMESPACE_ROLLBACK.equals(namespace)) {
+ return;
+ }
+ updateConfigs();
+ });
+ }
+
+ /**
+ * Health check is enabled or disabled after reading the flags
+ * from DeviceConfig.
+ */
+ private void updateConfigs() {
+ synchronized (mLock) {
+ mTriggerFailureCount = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_ROLLBACK,
+ PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT,
+ DEFAULT_TRIGGER_FAILURE_COUNT);
+ if (mTriggerFailureCount <= 0) {
+ mTriggerFailureCount = DEFAULT_TRIGGER_FAILURE_COUNT;
+ }
+
+ mTriggerFailureDurationMs = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_ROLLBACK,
+ PROPERTY_WATCHDOG_TRIGGER_DURATION_MILLIS,
+ DEFAULT_TRIGGER_FAILURE_DURATION_MS);
+ if (mTriggerFailureDurationMs <= 0) {
+ mTriggerFailureDurationMs = DEFAULT_TRIGGER_FAILURE_COUNT;
+ }
+
+ setExplicitHealthCheckEnabled(DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_ROLLBACK,
+ PROPERTY_WATCHDOG_EXPLICIT_HEALTH_CHECK_ENABLED,
+ DEFAULT_EXPLICIT_HEALTH_CHECK_ENABLED));
+ }
+ }
+
/**
* Persists mAllObservers to file. Threshold information is ignored.
*/
@@ -805,7 +871,7 @@
* #loadFromFile which in turn is only called on construction of the
* singleton PackageWatchdog.
**/
- public static ObserverInternal read(XmlPullParser parser) {
+ public static ObserverInternal read(XmlPullParser parser, PackageWatchdog watchdog) {
String observerName = null;
if (TAG_OBSERVER.equals(parser.getName())) {
observerName = parser.getAttributeValue(null, ATTR_NAME);
@@ -829,7 +895,7 @@
boolean hasPassedHealthCheck = Boolean.parseBoolean(
parser.getAttributeValue(null, ATTR_PASSED_HEALTH_CHECK));
if (!TextUtils.isEmpty(packageName)) {
- packages.add(new MonitoredPackage(packageName, duration,
+ packages.add(watchdog.new MonitoredPackage(packageName, duration,
healthCheckDuration, hasPassedHealthCheck));
}
} catch (NumberFormatException e) {
@@ -856,7 +922,7 @@
* <p> Note, the PackageWatchdog#mLock must always be held when reading or writing
* instances of this class.
*/
- static class MonitoredPackage {
+ class MonitoredPackage {
// Health check states
// TODO(b/120598832): Prefix with HEALTH_CHECK
// mName has not passed health check but has requested a health check
@@ -931,7 +997,7 @@
public boolean onFailureLocked() {
final long now = SystemClock.uptimeMillis();
final long duration = now - mUptimeStartMs;
- if (duration > TRIGGER_DURATION_MS) {
+ if (duration > mTriggerFailureDurationMs) {
// TODO(b/120598832): Reseting to 1 is not correct
// because there may be more than 1 failure in the last trigger window from now
// This is the RescueParty impl, will leave for now
@@ -940,7 +1006,7 @@
} else {
mFailures++;
}
- boolean failed = mFailures >= TRIGGER_FAILURE_COUNT;
+ boolean failed = mFailures >= mTriggerFailureCount;
if (failed) {
mFailures = 0;
}
@@ -1065,7 +1131,7 @@
}
/** Returns a {@link String} representation of the current health check state. */
- private static String toString(int state) {
+ private String toString(int state) {
switch (state) {
case STATE_ACTIVE:
return "ACTIVE";
@@ -1081,7 +1147,7 @@
}
/** Returns {@code value} if it is greater than 0 or {@link Long#MAX_VALUE} otherwise. */
- private static long toPositive(long value) {
+ private long toPositive(long value) {
return value > 0 ? value : Long.MAX_VALUE;
}
}
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index 1fe0271..fb1a962 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -72,8 +72,12 @@
static final int LEVEL_FACTORY_RESET = 4;
@VisibleForTesting
static final String PROP_RESCUE_BOOT_COUNT = "sys.rescue_boot_count";
+ /**
+ * The boot trigger window size must always be greater than Watchdog's deadlock timeout
+ * {@link Watchdog#DEFAULT_TIMEOUT}.
+ */
@VisibleForTesting
- static final long BOOT_TRIGGER_WINDOW_MILLIS = 300 * DateUtils.SECOND_IN_MILLIS;
+ static final long BOOT_TRIGGER_WINDOW_MILLIS = 600 * DateUtils.SECOND_IN_MILLIS;
@VisibleForTesting
static final long PERSISTENT_APP_CRASH_TRIGGER_WINDOW_MILLIS = 30 * DateUtils.SECOND_IN_MILLIS;
@VisibleForTesting
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 6c1ffa7..baec3cc 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -802,8 +802,8 @@
}
});
// For now, simply clone property when it changes
- DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_STORAGE,
- mContext.getMainExecutor(), (namespace, name, value) -> {
+ DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_STORAGE,
+ mContext.getMainExecutor(), (properties) -> {
refreshIsolatedStorageSettings();
});
refreshIsolatedStorageSettings();
@@ -1063,11 +1063,7 @@
}
private boolean supportsBlockCheckpoint() throws RemoteException {
- // Only the system process is permitted to start checkpoints
- if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
- throw new SecurityException("no permission to check block based checkpoint support");
- }
-
+ enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
return mVold.supportsBlockCheckpoint();
}
@@ -2726,11 +2722,7 @@
*/
@Override
public boolean needsCheckpoint() throws RemoteException {
- // Only the system process is permitted to commit checkpoints
- if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
- throw new SecurityException("no permission to commit checkpoint changes");
- }
-
+ enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
return mVold.needsCheckpoint();
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 76136df..df92106 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -634,7 +634,7 @@
}
if (allowBackgroundActivityStarts) {
- r.hasStartedWhitelistingBgActivityStarts = true;
+ r.setHasStartedWhitelistingBgActivityStarts(true);
scheduleCleanUpHasStartedWhitelistingBgActivityStartsLocked(r);
}
@@ -761,11 +761,6 @@
}
service.callStart = false;
- // the service will not necessarily be brought down, so only clear the whitelisting state
- // for start-based bg activity starts now, and drop any existing future cleanup callback
- service.setHasStartedWhitelistingBgActivityStarts(false);
- mAm.mHandler.removeCallbacks(service.startedWhitelistingBgActivityStartsCleanUp);
-
bringDownServiceIfNeededLocked(service, false, false);
}
@@ -1768,12 +1763,7 @@
callerApp.uid, callerApp.processName, callingPackage);
IBinder binder = connection.asBinder();
- ArrayList<ConnectionRecord> clist = s.getConnections().get(binder);
- if (clist == null) {
- clist = new ArrayList<ConnectionRecord>();
- s.putConnection(binder, clist);
- }
- clist.add(c);
+ s.addConnection(binder, c);
b.connections.add(c);
if (activity != null) {
activity.addConnection(c);
@@ -1792,9 +1782,9 @@
if (s.app != null) {
updateServiceClientActivitiesLocked(s.app, c, true);
}
- clist = mServiceConnections.get(binder);
+ ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
if (clist == null) {
- clist = new ArrayList<ConnectionRecord>();
+ clist = new ArrayList<>();
mServiceConnections.put(binder, clist);
}
clist.add(c);
@@ -3828,8 +3818,8 @@
public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) {
int userId = UserHandle.getUserId(Binder.getCallingUid());
ServiceRecord r = getServiceByNameLocked(name, userId);
- ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
if (r != null) {
+ ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
for (int conni = connections.size() - 1; conni >= 0; conni--) {
ArrayList<ConnectionRecord> conn = connections.valueAt(conni);
for (int i=0; i<conn.size(); i++) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index d7decb4..0da39e7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -26,7 +26,8 @@
import android.os.Build;
import android.os.Handler;
import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.OnPropertyChangedListener;
+import android.provider.DeviceConfig.OnPropertiesChangedListener;
+import android.provider.DeviceConfig.Properties;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
@@ -315,23 +316,25 @@
private static final Uri ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI =
Settings.Global.getUriFor(Settings.Global.ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS);
- private final OnPropertyChangedListener mOnDeviceConfigChangedListener =
- new OnPropertyChangedListener() {
+ private final OnPropertiesChangedListener mOnDeviceConfigChangedListener =
+ new OnPropertiesChangedListener() {
@Override
- public void onPropertyChanged(String namespace, String name, String value) {
- if (name == null) {
- return;
- }
- switch (name) {
- case KEY_MAX_CACHED_PROCESSES:
- updateMaxCachedProcesses();
- break;
- case KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED:
- case KEY_BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST:
- updateBackgroundActivityStarts();
- break;
- default:
- break;
+ public void onPropertiesChanged(Properties properties) {
+ for (String name : properties.getKeyset()) {
+ if (name == null) {
+ return;
+ }
+ switch (name) {
+ case KEY_MAX_CACHED_PROCESSES:
+ updateMaxCachedProcesses();
+ break;
+ case KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED:
+ case KEY_BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST:
+ updateBackgroundActivityStarts();
+ break;
+ default:
+ break;
+ }
}
}
};
@@ -362,7 +365,7 @@
if (mSystemServerAutomaticHeapDumpEnabled) {
updateEnableAutomaticSystemServerHeapDumps();
}
- DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
ActivityThread.currentApplication().getMainExecutor(),
mOnDeviceConfigChangedListener);
updateMaxCachedProcesses();
diff --git a/services/core/java/com/android/server/am/AppCompactor.java b/services/core/java/com/android/server/am/AppCompactor.java
index 13b55db..b0f8f86 100644
--- a/services/core/java/com/android/server/am/AppCompactor.java
+++ b/services/core/java/com/android/server/am/AppCompactor.java
@@ -30,7 +30,8 @@
import android.os.SystemClock;
import android.os.Trace;
import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.OnPropertyChangedListener;
+import android.provider.DeviceConfig.OnPropertiesChangedListener;
+import android.provider.DeviceConfig.Properties;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Slog;
@@ -126,29 +127,31 @@
private final ArrayList<ProcessRecord> mPendingCompactionProcesses =
new ArrayList<ProcessRecord>();
private final ActivityManagerService mAm;
- private final OnPropertyChangedListener mOnFlagsChangedListener =
- new OnPropertyChangedListener() {
+ private final OnPropertiesChangedListener mOnFlagsChangedListener =
+ new OnPropertiesChangedListener() {
@Override
- public void onPropertyChanged(String namespace, String name, String value) {
+ public void onPropertiesChanged(Properties properties) {
synchronized (mPhenotypeFlagLock) {
- if (KEY_USE_COMPACTION.equals(name)) {
- updateUseCompaction();
- } else if (KEY_COMPACT_ACTION_1.equals(name)
- || KEY_COMPACT_ACTION_2.equals(name)) {
- updateCompactionActions();
- } else if (KEY_COMPACT_THROTTLE_1.equals(name)
- || KEY_COMPACT_THROTTLE_2.equals(name)
- || KEY_COMPACT_THROTTLE_3.equals(name)
- || KEY_COMPACT_THROTTLE_4.equals(name)) {
- updateCompactionThrottles();
- } else if (KEY_COMPACT_STATSD_SAMPLE_RATE.equals(name)) {
- updateStatsdSampleRate();
- } else if (KEY_COMPACT_FULL_RSS_THROTTLE_KB.equals(name)) {
- updateFullRssThrottle();
- } else if (KEY_COMPACT_FULL_DELTA_RSS_THROTTLE_KB.equals(name)) {
- updateFullDeltaRssThrottle();
- } else if (KEY_COMPACT_PROC_STATE_THROTTLE.equals(name)) {
- updateProcStateThrottle();
+ for (String name : properties.getKeyset()) {
+ if (KEY_USE_COMPACTION.equals(name)) {
+ updateUseCompaction();
+ } else if (KEY_COMPACT_ACTION_1.equals(name)
+ || KEY_COMPACT_ACTION_2.equals(name)) {
+ updateCompactionActions();
+ } else if (KEY_COMPACT_THROTTLE_1.equals(name)
+ || KEY_COMPACT_THROTTLE_2.equals(name)
+ || KEY_COMPACT_THROTTLE_3.equals(name)
+ || KEY_COMPACT_THROTTLE_4.equals(name)) {
+ updateCompactionThrottles();
+ } else if (KEY_COMPACT_STATSD_SAMPLE_RATE.equals(name)) {
+ updateStatsdSampleRate();
+ } else if (KEY_COMPACT_FULL_RSS_THROTTLE_KB.equals(name)) {
+ updateFullRssThrottle();
+ } else if (KEY_COMPACT_FULL_DELTA_RSS_THROTTLE_KB.equals(name)) {
+ updateFullDeltaRssThrottle();
+ } else if (KEY_COMPACT_PROC_STATE_THROTTLE.equals(name)) {
+ updateProcStateThrottle();
+ }
}
}
if (mTestCallback != null) {
@@ -229,7 +232,7 @@
* starts the background thread if necessary.
*/
public void init() {
- DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
ActivityThread.currentApplication().getMainExecutor(), mOnFlagsChangedListener);
synchronized (mPhenotypeFlagLock) {
updateUseCompaction();
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index e891e6e..563b2f3 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -1186,8 +1186,8 @@
!mAllowBackgroundActivityStartsTokens.isEmpty());
}
- void addBoundClientUids(ArraySet<Integer> clientUids) {
- mBoundClientUids.addAll(clientUids);
+ void addBoundClientUid(int clientUid) {
+ mBoundClientUids.add(clientUid);
mWindowProcessController.setBoundClientUids(mBoundClientUids);
}
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 27c62d0..0426ec1 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -38,7 +38,6 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArrayMap;
-import android.util.ArraySet;
import android.util.Slog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
@@ -131,10 +130,10 @@
int pendingConnectionImportance; // To be filled in to ProcessRecord once it connects
// any current binding to this service has BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS flag?
- private boolean hasBindingWhitelistingBgActivityStarts;
+ private boolean mHasBindingWhitelistingBgActivityStarts;
// is this service currently whitelisted to start activities from background by providing
// allowBackgroundActivityStarts=true to startServiceLocked()?
- boolean hasStartedWhitelistingBgActivityStarts;
+ private boolean mHasStartedWhitelistingBgActivityStarts;
// used to clean up the state of hasStartedWhitelistingBgActivityStarts after a timeout
Runnable startedWhitelistingBgActivityStartsCleanUp;
@@ -384,13 +383,13 @@
if (whitelistManager) {
pw.print(prefix); pw.print("whitelistManager="); pw.println(whitelistManager);
}
- if (hasBindingWhitelistingBgActivityStarts) {
+ if (mHasBindingWhitelistingBgActivityStarts) {
pw.print(prefix); pw.print("hasBindingWhitelistingBgActivityStarts=");
- pw.println(hasBindingWhitelistingBgActivityStarts);
+ pw.println(mHasBindingWhitelistingBgActivityStarts);
}
- if (hasStartedWhitelistingBgActivityStarts) {
+ if (mHasStartedWhitelistingBgActivityStarts) {
pw.print(prefix); pw.print("hasStartedWhitelistingBgActivityStarts=");
- pw.println(hasStartedWhitelistingBgActivityStarts);
+ pw.println(mHasStartedWhitelistingBgActivityStarts);
}
if (delayed) {
pw.print(prefix); pw.print("delayed="); pw.println(delayed);
@@ -542,7 +541,8 @@
public void setProcess(ProcessRecord _proc) {
if (_proc != null) {
- if (hasStartedWhitelistingBgActivityStarts || hasBindingWhitelistingBgActivityStarts) {
+ if (mHasStartedWhitelistingBgActivityStarts
+ || mHasBindingWhitelistingBgActivityStarts) {
_proc.addAllowBackgroundActivityStartsToken(this);
} else {
_proc.removeAllowBackgroundActivityStartsToken(this);
@@ -580,15 +580,17 @@
return connections;
}
- void putConnection(IBinder binder, ArrayList<ConnectionRecord> clist) {
- connections.put(binder, clist);
- // if we have a process attached, add bound client uids of this connection to it
+ void addConnection(IBinder binder, ConnectionRecord c) {
+ ArrayList<ConnectionRecord> clist = connections.get(binder);
+ if (clist == null) {
+ clist = new ArrayList<>();
+ connections.put(binder, clist);
+ }
+ clist.add(c);
+
+ // if we have a process attached, add bound client uid of this connection to it
if (app != null) {
- ArraySet<Integer> boundClientUids = new ArraySet<>();
- for (int i = 0; i < clist.size(); i++) {
- boundClientUids.add(clist.get(i).clientUid);
- }
- app.addBoundClientUids(boundClientUids);
+ app.addBoundClientUid(c.clientUid);
}
}
@@ -614,22 +616,22 @@
break;
}
}
- if (hasBindingWhitelistingBgActivityStarts != hasWhitelistingBinding) {
- hasBindingWhitelistingBgActivityStarts = hasWhitelistingBinding;
+ if (mHasBindingWhitelistingBgActivityStarts != hasWhitelistingBinding) {
+ mHasBindingWhitelistingBgActivityStarts = hasWhitelistingBinding;
updateParentProcessBgActivityStartsWhitelistingToken();
}
}
void setHasBindingWhitelistingBgActivityStarts(boolean newValue) {
- if (hasBindingWhitelistingBgActivityStarts != newValue) {
- hasBindingWhitelistingBgActivityStarts = newValue;
+ if (mHasBindingWhitelistingBgActivityStarts != newValue) {
+ mHasBindingWhitelistingBgActivityStarts = newValue;
updateParentProcessBgActivityStartsWhitelistingToken();
}
}
void setHasStartedWhitelistingBgActivityStarts(boolean newValue) {
- if (hasStartedWhitelistingBgActivityStarts != newValue) {
- hasStartedWhitelistingBgActivityStarts = newValue;
+ if (mHasStartedWhitelistingBgActivityStarts != newValue) {
+ mHasStartedWhitelistingBgActivityStarts = newValue;
updateParentProcessBgActivityStartsWhitelistingToken();
}
}
@@ -647,7 +649,7 @@
if (app == null) {
return;
}
- if (hasStartedWhitelistingBgActivityStarts || hasBindingWhitelistingBgActivityStarts) {
+ if (mHasStartedWhitelistingBgActivityStarts || mHasBindingWhitelistingBgActivityStarts) {
// if the token is already there it's safe to "re-add it" - we're deadling with
// a set of Binder objects
app.addAllowBackgroundActivityStartsToken(this);
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 507f398..d510912 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1825,14 +1825,28 @@
&& streamTypeAlias == AudioSystem.STREAM_MUSIC
// vol change on a full volume device
&& ((device & mFullVolumeDevices) != 0)) {
- int keyCode = (direction == -1) ? KeyEvent.KEYCODE_VOLUME_DOWN :
- KeyEvent.KEYCODE_VOLUME_UP;
- final long ident = Binder.clearCallingIdentity();
- try {
- mHdmiPlaybackClient.sendKeyEvent(keyCode, true);
- mHdmiPlaybackClient.sendKeyEvent(keyCode, false);
- } finally {
- Binder.restoreCallingIdentity(ident);
+ int keyCode = KeyEvent.KEYCODE_UNKNOWN;
+ switch (direction) {
+ case AudioManager.ADJUST_RAISE:
+ keyCode = KeyEvent.KEYCODE_VOLUME_UP;
+ break;
+ case AudioManager.ADJUST_LOWER:
+ keyCode = KeyEvent.KEYCODE_VOLUME_DOWN;
+ break;
+ case AudioManager.ADJUST_TOGGLE_MUTE:
+ keyCode = KeyEvent.KEYCODE_VOLUME_MUTE;
+ break;
+ default:
+ break;
+ }
+ if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mHdmiPlaybackClient.sendKeyEvent(keyCode, true);
+ mHdmiPlaybackClient.sendKeyEvent(keyCode, false);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
}
}
diff --git a/services/core/java/com/android/server/gpu/GpuService.java b/services/core/java/com/android/server/gpu/GpuService.java
index 0f73f37..d439653 100644
--- a/services/core/java/com/android/server/gpu/GpuService.java
+++ b/services/core/java/com/android/server/gpu/GpuService.java
@@ -37,6 +37,7 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.Properties;
import android.provider.Settings;
import android.util.Base64;
import android.util.Slog;
@@ -138,18 +139,19 @@
}
}
- private final class DeviceConfigListener implements DeviceConfig.OnPropertyChangedListener {
+ private final class DeviceConfigListener implements DeviceConfig.OnPropertiesChangedListener {
DeviceConfigListener() {
super();
- DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_GAME_DRIVER,
+ DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_GAME_DRIVER,
mContext.getMainExecutor(), this);
}
@Override
- public void onPropertyChanged(String namespace, String name, String value) {
+ public void onPropertiesChanged(Properties properties) {
synchronized (mDeviceConfigLock) {
- if (Settings.Global.GAME_DRIVER_BLACKLISTS.equals(name)) {
- parseBlacklists(value != null ? value : "");
+ if (properties.getKeyset().contains(Settings.Global.GAME_DRIVER_BLACKLISTS)) {
+ parseBlacklists(
+ properties.getString(Settings.Global.GAME_DRIVER_BLACKLISTS, ""));
setBlacklist();
}
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 651ce7d..30d244f 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -1409,7 +1409,7 @@
mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
- mImeDisplayValidator = mWindowManagerInternal::shouldShowSystemDecorOnDisplay;
+ mImeDisplayValidator = displayId -> mWindowManagerInternal.shouldShowIme(displayId);
mCaller = new HandlerCaller(context, null, new HandlerCaller.Callback() {
@Override
public void executeMessage(Message msg) {
@@ -2139,7 +2139,9 @@
if (displayId == DEFAULT_DISPLAY || displayId == INVALID_DISPLAY) {
return FALLBACK_DISPLAY_ID;
}
- // Show IME window on fallback display when the display is not allowed.
+
+ // Show IME window on fallback display when the display doesn't support system decorations
+ // or the display is virtual and isn't owned by system for security concern.
return checker.displayCanShowIme(displayId) ? displayId : FALLBACK_DISPLAY_ID;
}
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index 580150e..e0b8e71 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -79,6 +79,9 @@
import com.android.internal.inputmethod.UnbindReason;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.os.TransferPipe;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
@@ -90,6 +93,8 @@
import com.android.server.wm.WindowManagerInternal;
import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.util.Collections;
import java.util.List;
@@ -645,6 +650,14 @@
mSelfReportedDisplayId = selfReportedDisplayId;
mClientId = InputMethodClientIdSource.getNext();
}
+
+ @GuardedBy("PerUserData.mLock")
+ void dumpLocked(FileDescriptor fd, IndentingPrintWriter ipw, String[] args) {
+ ipw.println("mState=" + mState + ",mBindingSequence=" + mBindingSequence
+ + ",mWriteChannel=" + mWriteChannel
+ + ",mInputMethodSession=" + mInputMethodSession
+ + ",mMSInputMethodSession=" + mMSInputMethodSession);
+ }
}
private static final class UserDataMap {
@@ -673,6 +686,22 @@
return mMap.removeReturnOld(userId);
}
}
+
+ @AnyThread
+ void dump(FileDescriptor fd, IndentingPrintWriter ipw, String[] args) {
+ synchronized (mMap) {
+ for (int i = 0; i < mMap.size(); i++) {
+ int userId = mMap.keyAt(i);
+ PerUserData data = mMap.valueAt(i);
+ ipw.println("userId=" + userId + ", data=");
+ if (data != null) {
+ ipw.increaseIndent();
+ data.dump(fd, ipw, args);
+ ipw.decreaseIndent();
+ }
+ }
+ }
+ }
}
private static final class TokenInfo {
@@ -967,6 +996,71 @@
}
}
+ @AnyThread
+ void dump(FileDescriptor fd, IndentingPrintWriter ipw, String[] args) {
+ synchronized (mLock) {
+ ipw.println("mState=" + mState
+ + ",mCurrentInputMethod=" + mCurrentInputMethod
+ + ",mCurrentInputMethodInfo=" + mCurrentInputMethodInfo);
+
+ if (mCurrentInputMethod != null) {
+ // indentation will not be kept. So add visual separator here.
+ ipw.println(">>Dump CurrentInputMethod>>");
+ ipw.flush();
+ try {
+ TransferPipe.dumpAsync(mCurrentInputMethod.asBinder(), fd, args);
+ } catch (IOException | RemoteException e) {
+ ipw.println("Failed to dump input method service: " + e);
+ }
+ ipw.println("<<Dump CurrentInputMethod<<");
+ }
+
+ ipw.println("mDisplayIdToImeWindowTokenMap=");
+ for (TokenInfo info : mDisplayIdToImeWindowTokenMap) {
+ ipw.println(" display=" + info.mDisplayId + ",token="
+ + info.mToken);
+ }
+ ipw.println("mClientMap=");
+ ipw.increaseIndent();
+ for (int i = 0; i < mClientMap.size(); i++) {
+
+ ipw.println("binder=" + mClientMap.keyAt(i));
+ ipw.println(" InputMethodClientInfo=");
+ InputMethodClientInfo info = mClientMap.valueAt(i);
+ if (info != null) {
+ ipw.increaseIndent();
+ info.dumpLocked(fd, ipw, args);
+ ipw.decreaseIndent();
+ }
+ }
+ ipw.decreaseIndent();
+ ipw.println("mClientIdToClientMap=");
+ ipw.increaseIndent();
+ for (int i = 0; i < mClientIdToClientMap.size(); i++) {
+ ipw.println("clientId=" + mClientIdToClientMap.keyAt(i));
+ ipw.println(" InputMethodClientInfo=");
+ InputMethodClientInfo info = mClientIdToClientMap.valueAt(i);
+ if (info != null) {
+ ipw.increaseIndent();
+ info.dumpLocked(fd, ipw, args);
+ ipw.decreaseIndent();
+ }
+ if (info.mClient != null) {
+ // indentation will not be kept. So add visual separator here.
+ ipw.println(">>DumpClientStart>>");
+ ipw.flush(); // all writes should be flushed to guarantee order.
+ try {
+ TransferPipe.dumpAsync(info.mClient.asBinder(), fd, args);
+ } catch (IOException | RemoteException e) {
+ ipw.println(" Failed to dump client:" + e);
+ }
+ ipw.println("<<DumpClientEnd<<");
+ }
+ }
+ ipw.decreaseIndent();
+ }
+ }
+
private static final class ClientDeathRecipient implements IBinder.DeathRecipient {
private final PerUserData mPerUserData;
private final IInputMethodClient mClient;
@@ -1106,6 +1200,16 @@
}
return Collections.singletonList(info);
}
+
+ @AnyThread
+ void dump(FileDescriptor fd, IndentingPrintWriter ipw, String[] args) {
+ synchronized (mArray) {
+ for (int i = 0; i < mArray.size(); i++) {
+ ipw.println("userId=" + mArray.keyAt(i));
+ ipw.println(" InputMethodInfo=" + mArray.valueAt(i));
+ }
+ }
+ }
}
/**
@@ -1601,5 +1705,19 @@
@Nullable FileDescriptor err, String[] args, @Nullable ShellCallback callback,
ResultReceiver resultReceiver) {
}
+
+ @BinderThread
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+ final String prefixChild = " ";
+ pw.println("Current Multi Client Input Method Manager state:");
+ IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ ipw.println("mUserDataMap=");
+ if (mUserDataMap != null) {
+ ipw.increaseIndent();
+ mUserDataMap.dump(fd, ipw, args);
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 3a397cd..b676618 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -464,32 +464,6 @@
private static final String KEY_CONN_CONGESTION_DELAY_FRAC = "conn_congestion_delay_frac";
private static final String KEY_CONN_PREFETCH_RELAX_FRAC = "conn_prefetch_relax_frac";
private static final String KEY_USE_HEARTBEATS = "use_heartbeats";
- private static final String KEY_TIME_CONTROLLER_SKIP_NOT_READY_JOBS =
- "tc_skip_not_ready_jobs";
- private static final String KEY_QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS =
- "qc_allowed_time_per_period_ms";
- private static final String KEY_QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS =
- "qc_in_quota_buffer_ms";
- private static final String KEY_QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS =
- "qc_window_size_active_ms";
- private static final String KEY_QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS =
- "qc_window_size_working_ms";
- private static final String KEY_QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS =
- "qc_window_size_frequent_ms";
- private static final String KEY_QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS =
- "qc_window_size_rare_ms";
- private static final String KEY_QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS =
- "qc_max_execution_time_ms";
- private static final String KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE =
- "qc_max_job_count_active";
- private static final String KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING =
- "qc_max_job_count_working";
- private static final String KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT =
- "qc_max_job_count_frequent";
- private static final String KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE =
- "qc_max_job_count_rare";
- private static final String KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME =
- "qc_max_count_per_allowed_time";
private static final int DEFAULT_MIN_IDLE_COUNT = 1;
private static final int DEFAULT_MIN_CHARGING_COUNT = 1;
@@ -511,30 +485,6 @@
private static final float DEFAULT_CONN_CONGESTION_DELAY_FRAC = 0.5f;
private static final float DEFAULT_CONN_PREFETCH_RELAX_FRAC = 0.5f;
private static final boolean DEFAULT_USE_HEARTBEATS = false;
- private static final boolean DEFAULT_TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
- private static final long DEFAULT_QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS =
- 10 * 60 * 1000L; // 10 minutes
- private static final long DEFAULT_QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS =
- 30 * 1000L; // 30 seconds
- private static final long DEFAULT_QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS =
- 10 * 60 * 1000L; // 10 minutes for ACTIVE -- ACTIVE apps can run jobs at any time
- private static final long DEFAULT_QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS =
- 2 * 60 * 60 * 1000L; // 2 hours
- private static final long DEFAULT_QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS =
- 8 * 60 * 60 * 1000L; // 8 hours
- private static final long DEFAULT_QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS =
- 24 * 60 * 60 * 1000L; // 24 hours
- private static final long DEFAULT_QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS =
- 4 * 60 * 60 * 1000L; // 4 hours
- private static final int DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE =
- 200; // 1200/hr
- private static final int DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING =
- 1200; // 600/hr
- private static final int DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT =
- 1800; // 225/hr
- private static final int DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE =
- 2400; // 100/hr
- private static final int DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME = 20;
/**
* Minimum # of idle jobs that must be ready in order to force the JMS to schedule things
@@ -681,97 +631,6 @@
*/
public boolean USE_HEARTBEATS = DEFAULT_USE_HEARTBEATS;
- /**
- * Whether or not TimeController should skip setting wakeup alarms for jobs that aren't
- * ready now.
- */
- public boolean TIME_CONTROLLER_SKIP_NOT_READY_JOBS =
- DEFAULT_TIME_CONTROLLER_SKIP_NOT_READY_JOBS;
-
- /** How much time each app will have to run jobs within their standby bucket window. */
- public long QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS =
- DEFAULT_QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS;
-
- /**
- * How much time the package should have before transitioning from out-of-quota to in-quota.
- * This should not affect processing if the package is already in-quota.
- */
- public long QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS =
- DEFAULT_QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
-
- /**
- * The quota window size of the particular standby bucket. Apps in this standby bucket are
- * expected to run only {@link #QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS} within the past
- * WINDOW_SIZE_MS.
- */
- public long QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS =
- DEFAULT_QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS;
-
- /**
- * The quota window size of the particular standby bucket. Apps in this standby bucket are
- * expected to run only {@link #QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS} within the past
- * WINDOW_SIZE_MS.
- */
- public long QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS =
- DEFAULT_QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS;
-
- /**
- * The quota window size of the particular standby bucket. Apps in this standby bucket are
- * expected to run only {@link #QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS} within the past
- * WINDOW_SIZE_MS.
- */
- public long QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS =
- DEFAULT_QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS;
-
- /**
- * The quota window size of the particular standby bucket. Apps in this standby bucket are
- * expected to run only {@link #QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS} within the past
- * WINDOW_SIZE_MS.
- */
- public long QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS =
- DEFAULT_QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS;
-
- /**
- * The maximum amount of time an app can have its jobs running within a 24 hour window.
- */
- public long QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS =
- DEFAULT_QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS;
-
- /**
- * The maximum number of jobs an app can run within this particular standby bucket's
- * window size.
- */
- public int QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE =
- DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE;
-
- /**
- * The maximum number of jobs an app can run within this particular standby bucket's
- * window size.
- */
- public int QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING =
- DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING;
-
- /**
- * The maximum number of jobs an app can run within this particular standby bucket's
- * window size.
- */
- public int QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT =
- DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT;
-
- /**
- * The maximum number of jobs an app can run within this particular standby bucket's
- * window size.
- */
- public int QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE =
- DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE;
-
- /**
- * The maximum number of jobs that can run within the past
- * {@link #QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS}.
- */
- public int QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME =
- DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME;
-
private final KeyValueListParser mParser = new KeyValueListParser(',');
void updateConstantsLocked(String value) {
@@ -835,45 +694,6 @@
CONN_PREFETCH_RELAX_FRAC = mParser.getFloat(KEY_CONN_PREFETCH_RELAX_FRAC,
DEFAULT_CONN_PREFETCH_RELAX_FRAC);
USE_HEARTBEATS = mParser.getBoolean(KEY_USE_HEARTBEATS, DEFAULT_USE_HEARTBEATS);
- TIME_CONTROLLER_SKIP_NOT_READY_JOBS = mParser.getBoolean(
- KEY_TIME_CONTROLLER_SKIP_NOT_READY_JOBS,
- DEFAULT_TIME_CONTROLLER_SKIP_NOT_READY_JOBS);
- QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS = mParser.getDurationMillis(
- KEY_QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS,
- DEFAULT_QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS);
- QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS = mParser.getDurationMillis(
- KEY_QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS,
- DEFAULT_QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS);
- QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS = mParser.getDurationMillis(
- KEY_QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS,
- DEFAULT_QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS);
- QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS = mParser.getDurationMillis(
- KEY_QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS,
- DEFAULT_QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS);
- QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS = mParser.getDurationMillis(
- KEY_QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS,
- DEFAULT_QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS);
- QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS = mParser.getDurationMillis(
- KEY_QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS,
- DEFAULT_QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS);
- QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS = mParser.getDurationMillis(
- KEY_QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS,
- DEFAULT_QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS);
- QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE = mParser.getInt(
- KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE,
- DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE);
- QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING = mParser.getInt(
- KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING,
- DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING);
- QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT = mParser.getInt(
- KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT,
- DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT);
- QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE = mParser.getInt(
- KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE,
- DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE);
- QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME = mParser.getInt(
- KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME,
- DEFAULT_QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME);
}
void dump(IndentingPrintWriter pw) {
@@ -916,37 +736,11 @@
pw.printPair(KEY_CONN_CONGESTION_DELAY_FRAC, CONN_CONGESTION_DELAY_FRAC).println();
pw.printPair(KEY_CONN_PREFETCH_RELAX_FRAC, CONN_PREFETCH_RELAX_FRAC).println();
pw.printPair(KEY_USE_HEARTBEATS, USE_HEARTBEATS).println();
- pw.printPair(KEY_TIME_CONTROLLER_SKIP_NOT_READY_JOBS,
- TIME_CONTROLLER_SKIP_NOT_READY_JOBS).println();
- pw.printPair(KEY_QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS,
- QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS).println();
- pw.printPair(KEY_QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS,
- QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS).println();
- pw.printPair(KEY_QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS,
- QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS).println();
- pw.printPair(KEY_QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS,
- QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS).println();
- pw.printPair(KEY_QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS,
- QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS).println();
- pw.printPair(KEY_QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS,
- QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS).println();
- pw.printPair(KEY_QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS,
- QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS).println();
- pw.printPair(KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE,
- QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE).println();
- pw.printPair(KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING,
- QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING).println();
- pw.printPair(KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT,
- QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT).println();
- pw.printPair(KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE,
- QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE).println();
- pw.printPair(KEY_QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME,
- QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME).println();
+
pw.decreaseIndent();
}
- void dump(ProtoOutputStream proto, long fieldId) {
- final long token = proto.start(fieldId);
+ void dump(ProtoOutputStream proto) {
proto.write(ConstantsProto.MIN_IDLE_COUNT, MIN_IDLE_COUNT);
proto.write(ConstantsProto.MIN_CHARGING_COUNT, MIN_CHARGING_COUNT);
proto.write(ConstantsProto.MIN_BATTERY_NOT_LOW_COUNT, MIN_BATTERY_NOT_LOW_COUNT);
@@ -974,40 +768,6 @@
proto.write(ConstantsProto.CONN_CONGESTION_DELAY_FRAC, CONN_CONGESTION_DELAY_FRAC);
proto.write(ConstantsProto.CONN_PREFETCH_RELAX_FRAC, CONN_PREFETCH_RELAX_FRAC);
proto.write(ConstantsProto.USE_HEARTBEATS, USE_HEARTBEATS);
-
- final long tcToken = proto.start(ConstantsProto.TIME_CONTROLLER);
- proto.write(ConstantsProto.TimeController.SKIP_NOT_READY_JOBS,
- TIME_CONTROLLER_SKIP_NOT_READY_JOBS);
- proto.end(tcToken);
-
- final long qcToken = proto.start(ConstantsProto.QUOTA_CONTROLLER);
- proto.write(ConstantsProto.QuotaController.ALLOWED_TIME_PER_PERIOD_MS,
- QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS);
- proto.write(ConstantsProto.QuotaController.IN_QUOTA_BUFFER_MS,
- QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS);
- proto.write(ConstantsProto.QuotaController.ACTIVE_WINDOW_SIZE_MS,
- QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS);
- proto.write(ConstantsProto.QuotaController.WORKING_WINDOW_SIZE_MS,
- QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS);
- proto.write(ConstantsProto.QuotaController.FREQUENT_WINDOW_SIZE_MS,
- QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS);
- proto.write(ConstantsProto.QuotaController.RARE_WINDOW_SIZE_MS,
- QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS);
- proto.write(ConstantsProto.QuotaController.MAX_EXECUTION_TIME_MS,
- QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS);
- proto.write(ConstantsProto.QuotaController.MAX_JOB_COUNT_ACTIVE,
- QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE);
- proto.write(ConstantsProto.QuotaController.MAX_JOB_COUNT_WORKING,
- QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING);
- proto.write(ConstantsProto.QuotaController.MAX_JOB_COUNT_FREQUENT,
- QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT);
- proto.write(ConstantsProto.QuotaController.MAX_JOB_COUNT_RARE,
- QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE);
- proto.write(ConstantsProto.QuotaController.MAX_JOB_COUNT_PER_ALLOWED_TIME,
- QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME);
- proto.end(qcToken);
-
- proto.end(token);
}
}
@@ -1637,6 +1397,9 @@
public void onBootPhase(int phase) {
if (PHASE_SYSTEM_SERVICES_READY == phase) {
mConstantsObserver.start(getContext().getContentResolver());
+ for (StateController controller : mControllers) {
+ controller.onSystemServicesReady();
+ }
mAppStateTracker = Preconditions.checkNotNull(
LocalServices.getService(AppStateTracker.class));
@@ -3448,6 +3211,11 @@
};
synchronized (mLock) {
mConstants.dump(pw);
+ for (StateController controller : mControllers) {
+ pw.increaseIndent();
+ controller.dumpConstants(pw);
+ pw.decreaseIndent();
+ }
pw.println();
pw.println(" Heartbeat:");
@@ -3638,7 +3406,13 @@
};
synchronized (mLock) {
- mConstants.dump(proto, JobSchedulerServiceDumpProto.SETTINGS);
+ final long settingsToken = proto.start(JobSchedulerServiceDumpProto.SETTINGS);
+ mConstants.dump(proto);
+ for (StateController controller : mControllers) {
+ controller.dumpConstants(proto);
+ }
+ proto.end(settingsToken);
+
proto.write(JobSchedulerServiceDumpProto.CURRENT_HEARTBEAT, mHeartbeat);
proto.write(JobSchedulerServiceDumpProto.NEXT_HEARTBEAT, mNextBucketHeartbeat[0]);
proto.write(JobSchedulerServiceDumpProto.NEXT_HEARTBEAT, mNextBucketHeartbeat[1]);
diff --git a/services/core/java/com/android/server/job/controllers/QuotaController.java b/services/core/java/com/android/server/job/controllers/QuotaController.java
index 11f0939..2a9d3f3 100644
--- a/services/core/java/com/android/server/job/controllers/QuotaController.java
+++ b/services/core/java/com/android/server/job/controllers/QuotaController.java
@@ -34,9 +34,12 @@
import android.app.usage.UsageStatsManagerInternal;
import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.Uri;
import android.os.BatteryManager;
import android.os.BatteryManagerInternal;
import android.os.Handler;
@@ -44,8 +47,10 @@
import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.KeyValueListParser;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
@@ -57,6 +62,7 @@
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
+import com.android.server.job.ConstantsProto;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateControllerProto;
@@ -354,6 +360,7 @@
private final AlarmManager mAlarmManager;
private final ChargingTracker mChargeTracker;
private final Handler mHandler;
+ private final QcConstants mQcConstants;
private volatile boolean mInParole;
@@ -489,6 +496,7 @@
mChargeTracker.startTracking();
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+ mQcConstants = new QcConstants(mHandler);
final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
mContext.registerReceiverAsUser(mPackageAddedReceiver, UserHandle.ALL, filter, null, null);
@@ -506,7 +514,12 @@
// ignored; both services live in system_server
}
- onConstantsUpdatedLocked();
+ mShouldThrottle = !mConstants.USE_HEARTBEATS;
+ }
+
+ @Override
+ public void onSystemServicesReady() {
+ mQcConstants.start(mContext.getContentResolver());
}
@Override
@@ -581,89 +594,9 @@
@Override
public void onConstantsUpdatedLocked() {
- boolean changed = false;
if (mShouldThrottle == mConstants.USE_HEARTBEATS) {
mShouldThrottle = !mConstants.USE_HEARTBEATS;
- changed = true;
- }
- long newAllowedTimeMs = Math.min(MAX_PERIOD_MS,
- Math.max(MINUTE_IN_MILLIS, mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS));
- if (mAllowedTimePerPeriodMs != newAllowedTimeMs) {
- mAllowedTimePerPeriodMs = newAllowedTimeMs;
- mAllowedTimeIntoQuotaMs = mAllowedTimePerPeriodMs - mQuotaBufferMs;
- changed = true;
- }
- long newQuotaBufferMs = Math.max(0,
- Math.min(5 * MINUTE_IN_MILLIS, mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS));
- if (mQuotaBufferMs != newQuotaBufferMs) {
- mQuotaBufferMs = newQuotaBufferMs;
- mAllowedTimeIntoQuotaMs = mAllowedTimePerPeriodMs - mQuotaBufferMs;
- mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs;
- changed = true;
- }
- long newActivePeriodMs = Math.max(mAllowedTimePerPeriodMs,
- Math.min(MAX_PERIOD_MS, mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS));
- if (mBucketPeriodsMs[ACTIVE_INDEX] != newActivePeriodMs) {
- mBucketPeriodsMs[ACTIVE_INDEX] = newActivePeriodMs;
- changed = true;
- }
- long newWorkingPeriodMs = Math.max(mAllowedTimePerPeriodMs,
- Math.min(MAX_PERIOD_MS, mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS));
- if (mBucketPeriodsMs[WORKING_INDEX] != newWorkingPeriodMs) {
- mBucketPeriodsMs[WORKING_INDEX] = newWorkingPeriodMs;
- changed = true;
- }
- long newFrequentPeriodMs = Math.max(mAllowedTimePerPeriodMs,
- Math.min(MAX_PERIOD_MS, mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS));
- if (mBucketPeriodsMs[FREQUENT_INDEX] != newFrequentPeriodMs) {
- mBucketPeriodsMs[FREQUENT_INDEX] = newFrequentPeriodMs;
- changed = true;
- }
- long newRarePeriodMs = Math.max(mAllowedTimePerPeriodMs,
- Math.min(MAX_PERIOD_MS, mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS));
- if (mBucketPeriodsMs[RARE_INDEX] != newRarePeriodMs) {
- mBucketPeriodsMs[RARE_INDEX] = newRarePeriodMs;
- changed = true;
- }
- long newMaxExecutionTimeMs = Math.max(60 * MINUTE_IN_MILLIS,
- Math.min(MAX_PERIOD_MS, mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS));
- if (mMaxExecutionTimeMs != newMaxExecutionTimeMs) {
- mMaxExecutionTimeMs = newMaxExecutionTimeMs;
- mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs;
- changed = true;
- }
- int newMaxCountPerAllowedPeriod = Math.max(10,
- mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME);
- if (mMaxJobCountPerAllowedTime != newMaxCountPerAllowedPeriod) {
- mMaxJobCountPerAllowedTime = newMaxCountPerAllowedPeriod;
- changed = true;
- }
- int newActiveMaxJobCount = Math.max(mMaxJobCountPerAllowedTime,
- Math.max(MIN_BUCKET_JOB_COUNT, mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE));
- if (mMaxBucketJobCounts[ACTIVE_INDEX] != newActiveMaxJobCount) {
- mMaxBucketJobCounts[ACTIVE_INDEX] = newActiveMaxJobCount;
- changed = true;
- }
- int newWorkingMaxJobCount = Math.max(mMaxJobCountPerAllowedTime,
- Math.max(MIN_BUCKET_JOB_COUNT, mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING));
- if (mMaxBucketJobCounts[WORKING_INDEX] != newWorkingMaxJobCount) {
- mMaxBucketJobCounts[WORKING_INDEX] = newWorkingMaxJobCount;
- changed = true;
- }
- int newFrequentMaxJobCount = Math.max(mMaxJobCountPerAllowedTime,
- Math.max(MIN_BUCKET_JOB_COUNT, mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT));
- if (mMaxBucketJobCounts[FREQUENT_INDEX] != newFrequentMaxJobCount) {
- mMaxBucketJobCounts[FREQUENT_INDEX] = newFrequentMaxJobCount;
- changed = true;
- }
- int newRareMaxJobCount = Math.max(mMaxJobCountPerAllowedTime,
- Math.max(MIN_BUCKET_JOB_COUNT, mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE));
- if (mMaxBucketJobCounts[RARE_INDEX] != newRareMaxJobCount) {
- mMaxBucketJobCounts[RARE_INDEX] = newRareMaxJobCount;
- changed = true;
- }
- if (changed) {
// Update job bookkeeping out of band.
BackgroundThread.getHandler().post(() -> {
synchronized (mLock) {
@@ -1891,6 +1824,311 @@
}
}
+ @VisibleForTesting
+ class QcConstants extends ContentObserver {
+ private ContentResolver mResolver;
+ private final KeyValueListParser mParser = new KeyValueListParser(',');
+
+ private static final String KEY_ALLOWED_TIME_PER_PERIOD_MS = "allowed_time_per_period_ms";
+ private static final String KEY_IN_QUOTA_BUFFER_MS = "in_quota_buffer_ms";
+ private static final String KEY_WINDOW_SIZE_ACTIVE_MS = "window_size_active_ms";
+ private static final String KEY_WINDOW_SIZE_WORKING_MS = "window_size_working_ms";
+ private static final String KEY_WINDOW_SIZE_FREQUENT_MS = "window_size_frequent_ms";
+ private static final String KEY_WINDOW_SIZE_RARE_MS = "window_size_rare_ms";
+ private static final String KEY_MAX_EXECUTION_TIME_MS = "max_execution_time_ms";
+ private static final String KEY_MAX_JOB_COUNT_ACTIVE = "max_job_count_active";
+ private static final String KEY_MAX_JOB_COUNT_WORKING = "max_job_count_working";
+ private static final String KEY_MAX_JOB_COUNT_FREQUENT = "max_job_count_frequent";
+ private static final String KEY_MAX_JOB_COUNT_RARE = "max_job_count_rare";
+ private static final String KEY_MAX_JOB_COUNT_PER_ALLOWED_TIME =
+ "max_count_per_allowed_time";
+
+ private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_MS =
+ 10 * 60 * 1000L; // 10 minutes
+ private static final long DEFAULT_IN_QUOTA_BUFFER_MS =
+ 30 * 1000L; // 30 seconds
+ private static final long DEFAULT_WINDOW_SIZE_ACTIVE_MS =
+ 10 * 60 * 1000L; // 10 minutes for ACTIVE -- ACTIVE apps can run jobs at any time
+ private static final long DEFAULT_WINDOW_SIZE_WORKING_MS =
+ 2 * 60 * 60 * 1000L; // 2 hours
+ private static final long DEFAULT_WINDOW_SIZE_FREQUENT_MS =
+ 8 * 60 * 60 * 1000L; // 8 hours
+ private static final long DEFAULT_WINDOW_SIZE_RARE_MS =
+ 24 * 60 * 60 * 1000L; // 24 hours
+ private static final long DEFAULT_MAX_EXECUTION_TIME_MS =
+ 4 * 60 * 60 * 1000L; // 4 hours
+ private static final int DEFAULT_MAX_JOB_COUNT_ACTIVE =
+ 200; // 1200/hr
+ private static final int DEFAULT_MAX_JOB_COUNT_WORKING =
+ 1200; // 600/hr
+ private static final int DEFAULT_MAX_JOB_COUNT_FREQUENT =
+ 1800; // 225/hr
+ private static final int DEFAULT_MAX_JOB_COUNT_RARE =
+ 2400; // 100/hr
+ private static final int DEFAULT_MAX_JOB_COUNT_PER_ALLOWED_TIME = 20;
+
+ /** How much time each app will have to run jobs within their standby bucket window. */
+ public long ALLOWED_TIME_PER_PERIOD_MS = DEFAULT_ALLOWED_TIME_PER_PERIOD_MS;
+
+ /**
+ * How much time the package should have before transitioning from out-of-quota to in-quota.
+ * This should not affect processing if the package is already in-quota.
+ */
+ public long IN_QUOTA_BUFFER_MS = DEFAULT_IN_QUOTA_BUFFER_MS;
+
+ /**
+ * The quota window size of the particular standby bucket. Apps in this standby bucket are
+ * expected to run only {@link #ALLOWED_TIME_PER_PERIOD_MS} within the past
+ * WINDOW_SIZE_MS.
+ */
+ public long WINDOW_SIZE_ACTIVE_MS = DEFAULT_WINDOW_SIZE_ACTIVE_MS;
+
+ /**
+ * The quota window size of the particular standby bucket. Apps in this standby bucket are
+ * expected to run only {@link #ALLOWED_TIME_PER_PERIOD_MS} within the past
+ * WINDOW_SIZE_MS.
+ */
+ public long WINDOW_SIZE_WORKING_MS = DEFAULT_WINDOW_SIZE_WORKING_MS;
+
+ /**
+ * The quota window size of the particular standby bucket. Apps in this standby bucket are
+ * expected to run only {@link #ALLOWED_TIME_PER_PERIOD_MS} within the past
+ * WINDOW_SIZE_MS.
+ */
+ public long WINDOW_SIZE_FREQUENT_MS = DEFAULT_WINDOW_SIZE_FREQUENT_MS;
+
+ /**
+ * The quota window size of the particular standby bucket. Apps in this standby bucket are
+ * expected to run only {@link #ALLOWED_TIME_PER_PERIOD_MS} within the past
+ * WINDOW_SIZE_MS.
+ */
+ public long WINDOW_SIZE_RARE_MS = DEFAULT_WINDOW_SIZE_RARE_MS;
+
+ /**
+ * The maximum amount of time an app can have its jobs running within a 24 hour window.
+ */
+ public long MAX_EXECUTION_TIME_MS = DEFAULT_MAX_EXECUTION_TIME_MS;
+
+ /**
+ * The maximum number of jobs an app can run within this particular standby bucket's
+ * window size.
+ */
+ public int MAX_JOB_COUNT_ACTIVE = DEFAULT_MAX_JOB_COUNT_ACTIVE;
+
+ /**
+ * The maximum number of jobs an app can run within this particular standby bucket's
+ * window size.
+ */
+ public int MAX_JOB_COUNT_WORKING = DEFAULT_MAX_JOB_COUNT_WORKING;
+
+ /**
+ * The maximum number of jobs an app can run within this particular standby bucket's
+ * window size.
+ */
+ public int MAX_JOB_COUNT_FREQUENT = DEFAULT_MAX_JOB_COUNT_FREQUENT;
+
+ /**
+ * The maximum number of jobs an app can run within this particular standby bucket's
+ * window size.
+ */
+ public int MAX_JOB_COUNT_RARE = DEFAULT_MAX_JOB_COUNT_RARE;
+
+ /**
+ * The maximum number of jobs that can run within the past
+ * {@link #ALLOWED_TIME_PER_PERIOD_MS}.
+ */
+ public int MAX_JOB_COUNT_PER_ALLOWED_TIME = DEFAULT_MAX_JOB_COUNT_PER_ALLOWED_TIME;
+
+ QcConstants(Handler handler) {
+ super(handler);
+ }
+
+ private void start(ContentResolver resolver) {
+ mResolver = resolver;
+ mResolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS), false, this);
+ updateConstants();
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ final String constants = Settings.Global.getString(
+ mResolver, Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS);
+
+ try {
+ mParser.setString(constants);
+ } catch (Exception e) {
+ // Failed to parse the settings string, log this and move on with defaults.
+ Slog.e(TAG, "Bad jobscheduler quota controller settings", e);
+ }
+
+ ALLOWED_TIME_PER_PERIOD_MS = mParser.getDurationMillis(
+ KEY_ALLOWED_TIME_PER_PERIOD_MS, DEFAULT_ALLOWED_TIME_PER_PERIOD_MS);
+ IN_QUOTA_BUFFER_MS = mParser.getDurationMillis(
+ KEY_IN_QUOTA_BUFFER_MS, DEFAULT_IN_QUOTA_BUFFER_MS);
+ WINDOW_SIZE_ACTIVE_MS = mParser.getDurationMillis(
+ KEY_WINDOW_SIZE_ACTIVE_MS, DEFAULT_WINDOW_SIZE_ACTIVE_MS);
+ WINDOW_SIZE_WORKING_MS = mParser.getDurationMillis(
+ KEY_WINDOW_SIZE_WORKING_MS, DEFAULT_WINDOW_SIZE_WORKING_MS);
+ WINDOW_SIZE_FREQUENT_MS = mParser.getDurationMillis(
+ KEY_WINDOW_SIZE_FREQUENT_MS, DEFAULT_WINDOW_SIZE_FREQUENT_MS);
+ WINDOW_SIZE_RARE_MS = mParser.getDurationMillis(
+ KEY_WINDOW_SIZE_RARE_MS, DEFAULT_WINDOW_SIZE_RARE_MS);
+ MAX_EXECUTION_TIME_MS = mParser.getDurationMillis(
+ KEY_MAX_EXECUTION_TIME_MS, DEFAULT_MAX_EXECUTION_TIME_MS);
+ MAX_JOB_COUNT_ACTIVE = mParser.getInt(
+ KEY_MAX_JOB_COUNT_ACTIVE, DEFAULT_MAX_JOB_COUNT_ACTIVE);
+ MAX_JOB_COUNT_WORKING = mParser.getInt(
+ KEY_MAX_JOB_COUNT_WORKING, DEFAULT_MAX_JOB_COUNT_WORKING);
+ MAX_JOB_COUNT_FREQUENT = mParser.getInt(
+ KEY_MAX_JOB_COUNT_FREQUENT, DEFAULT_MAX_JOB_COUNT_FREQUENT);
+ MAX_JOB_COUNT_RARE = mParser.getInt(
+ KEY_MAX_JOB_COUNT_RARE, DEFAULT_MAX_JOB_COUNT_RARE);
+ MAX_JOB_COUNT_PER_ALLOWED_TIME = mParser.getInt(
+ KEY_MAX_JOB_COUNT_PER_ALLOWED_TIME, DEFAULT_MAX_JOB_COUNT_PER_ALLOWED_TIME);
+
+ updateConstants();
+ }
+
+ @VisibleForTesting
+ void updateConstants() {
+ synchronized (mLock) {
+ boolean changed = false;
+
+ long newAllowedTimeMs = Math.min(MAX_PERIOD_MS,
+ Math.max(MINUTE_IN_MILLIS, ALLOWED_TIME_PER_PERIOD_MS));
+ if (mAllowedTimePerPeriodMs != newAllowedTimeMs) {
+ mAllowedTimePerPeriodMs = newAllowedTimeMs;
+ mAllowedTimeIntoQuotaMs = mAllowedTimePerPeriodMs - mQuotaBufferMs;
+ changed = true;
+ }
+ long newQuotaBufferMs = Math.max(0,
+ Math.min(5 * MINUTE_IN_MILLIS, IN_QUOTA_BUFFER_MS));
+ if (mQuotaBufferMs != newQuotaBufferMs) {
+ mQuotaBufferMs = newQuotaBufferMs;
+ mAllowedTimeIntoQuotaMs = mAllowedTimePerPeriodMs - mQuotaBufferMs;
+ mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs;
+ changed = true;
+ }
+ long newActivePeriodMs = Math.max(mAllowedTimePerPeriodMs,
+ Math.min(MAX_PERIOD_MS, WINDOW_SIZE_ACTIVE_MS));
+ if (mBucketPeriodsMs[ACTIVE_INDEX] != newActivePeriodMs) {
+ mBucketPeriodsMs[ACTIVE_INDEX] = newActivePeriodMs;
+ changed = true;
+ }
+ long newWorkingPeriodMs = Math.max(mAllowedTimePerPeriodMs,
+ Math.min(MAX_PERIOD_MS, WINDOW_SIZE_WORKING_MS));
+ if (mBucketPeriodsMs[WORKING_INDEX] != newWorkingPeriodMs) {
+ mBucketPeriodsMs[WORKING_INDEX] = newWorkingPeriodMs;
+ changed = true;
+ }
+ long newFrequentPeriodMs = Math.max(mAllowedTimePerPeriodMs,
+ Math.min(MAX_PERIOD_MS, WINDOW_SIZE_FREQUENT_MS));
+ if (mBucketPeriodsMs[FREQUENT_INDEX] != newFrequentPeriodMs) {
+ mBucketPeriodsMs[FREQUENT_INDEX] = newFrequentPeriodMs;
+ changed = true;
+ }
+ long newRarePeriodMs = Math.max(mAllowedTimePerPeriodMs,
+ Math.min(MAX_PERIOD_MS, WINDOW_SIZE_RARE_MS));
+ if (mBucketPeriodsMs[RARE_INDEX] != newRarePeriodMs) {
+ mBucketPeriodsMs[RARE_INDEX] = newRarePeriodMs;
+ changed = true;
+ }
+ long newMaxExecutionTimeMs = Math.max(60 * MINUTE_IN_MILLIS,
+ Math.min(MAX_PERIOD_MS, MAX_EXECUTION_TIME_MS));
+ if (mMaxExecutionTimeMs != newMaxExecutionTimeMs) {
+ mMaxExecutionTimeMs = newMaxExecutionTimeMs;
+ mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs;
+ changed = true;
+ }
+ int newMaxCountPerAllowedPeriod = Math.max(10,
+ MAX_JOB_COUNT_PER_ALLOWED_TIME);
+ if (mMaxJobCountPerAllowedTime != newMaxCountPerAllowedPeriod) {
+ mMaxJobCountPerAllowedTime = newMaxCountPerAllowedPeriod;
+ changed = true;
+ }
+ int newActiveMaxJobCount = Math.max(mMaxJobCountPerAllowedTime,
+ Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_ACTIVE));
+ if (mMaxBucketJobCounts[ACTIVE_INDEX] != newActiveMaxJobCount) {
+ mMaxBucketJobCounts[ACTIVE_INDEX] = newActiveMaxJobCount;
+ changed = true;
+ }
+ int newWorkingMaxJobCount = Math.max(mMaxJobCountPerAllowedTime,
+ Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_WORKING));
+ if (mMaxBucketJobCounts[WORKING_INDEX] != newWorkingMaxJobCount) {
+ mMaxBucketJobCounts[WORKING_INDEX] = newWorkingMaxJobCount;
+ changed = true;
+ }
+ int newFrequentMaxJobCount = Math.max(mMaxJobCountPerAllowedTime,
+ Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_FREQUENT));
+ if (mMaxBucketJobCounts[FREQUENT_INDEX] != newFrequentMaxJobCount) {
+ mMaxBucketJobCounts[FREQUENT_INDEX] = newFrequentMaxJobCount;
+ changed = true;
+ }
+ int newRareMaxJobCount = Math.max(mMaxJobCountPerAllowedTime,
+ Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_RARE));
+ if (mMaxBucketJobCounts[RARE_INDEX] != newRareMaxJobCount) {
+ mMaxBucketJobCounts[RARE_INDEX] = newRareMaxJobCount;
+ changed = true;
+ }
+
+ if (changed && mShouldThrottle) {
+ // Update job bookkeeping out of band.
+ BackgroundThread.getHandler().post(() -> {
+ synchronized (mLock) {
+ maybeUpdateAllConstraintsLocked();
+ }
+ });
+ }
+ }
+ }
+
+ private void dump(IndentingPrintWriter pw) {
+ pw.println();
+ pw.println("QuotaController:");
+ pw.increaseIndent();
+ pw.printPair(KEY_ALLOWED_TIME_PER_PERIOD_MS, ALLOWED_TIME_PER_PERIOD_MS).println();
+ pw.printPair(KEY_IN_QUOTA_BUFFER_MS, IN_QUOTA_BUFFER_MS).println();
+ pw.printPair(KEY_WINDOW_SIZE_ACTIVE_MS, WINDOW_SIZE_ACTIVE_MS).println();
+ pw.printPair(KEY_WINDOW_SIZE_WORKING_MS, WINDOW_SIZE_WORKING_MS).println();
+ pw.printPair(KEY_WINDOW_SIZE_FREQUENT_MS, WINDOW_SIZE_FREQUENT_MS).println();
+ pw.printPair(KEY_WINDOW_SIZE_RARE_MS, WINDOW_SIZE_RARE_MS).println();
+ pw.printPair(KEY_MAX_EXECUTION_TIME_MS, MAX_EXECUTION_TIME_MS).println();
+ pw.printPair(KEY_MAX_JOB_COUNT_ACTIVE, MAX_JOB_COUNT_ACTIVE).println();
+ pw.printPair(KEY_MAX_JOB_COUNT_WORKING, MAX_JOB_COUNT_WORKING).println();
+ pw.printPair(KEY_MAX_JOB_COUNT_FREQUENT, MAX_JOB_COUNT_FREQUENT).println();
+ pw.printPair(KEY_MAX_JOB_COUNT_RARE, MAX_JOB_COUNT_RARE).println();
+ pw.printPair(KEY_MAX_JOB_COUNT_PER_ALLOWED_TIME, MAX_JOB_COUNT_PER_ALLOWED_TIME)
+ .println();
+ pw.decreaseIndent();
+ }
+
+ private void dump(ProtoOutputStream proto) {
+ final long qcToken = proto.start(ConstantsProto.QUOTA_CONTROLLER);
+ proto.write(ConstantsProto.QuotaController.ALLOWED_TIME_PER_PERIOD_MS,
+ ALLOWED_TIME_PER_PERIOD_MS);
+ proto.write(ConstantsProto.QuotaController.IN_QUOTA_BUFFER_MS, IN_QUOTA_BUFFER_MS);
+ proto.write(ConstantsProto.QuotaController.ACTIVE_WINDOW_SIZE_MS,
+ WINDOW_SIZE_ACTIVE_MS);
+ proto.write(ConstantsProto.QuotaController.WORKING_WINDOW_SIZE_MS,
+ WINDOW_SIZE_WORKING_MS);
+ proto.write(ConstantsProto.QuotaController.FREQUENT_WINDOW_SIZE_MS,
+ WINDOW_SIZE_FREQUENT_MS);
+ proto.write(ConstantsProto.QuotaController.RARE_WINDOW_SIZE_MS, WINDOW_SIZE_RARE_MS);
+ proto.write(ConstantsProto.QuotaController.MAX_EXECUTION_TIME_MS,
+ MAX_EXECUTION_TIME_MS);
+ proto.write(ConstantsProto.QuotaController.MAX_JOB_COUNT_ACTIVE, MAX_JOB_COUNT_ACTIVE);
+ proto.write(ConstantsProto.QuotaController.MAX_JOB_COUNT_WORKING,
+ MAX_JOB_COUNT_WORKING);
+ proto.write(ConstantsProto.QuotaController.MAX_JOB_COUNT_FREQUENT,
+ MAX_JOB_COUNT_FREQUENT);
+ proto.write(ConstantsProto.QuotaController.MAX_JOB_COUNT_RARE, MAX_JOB_COUNT_RARE);
+ proto.write(ConstantsProto.QuotaController.MAX_JOB_COUNT_PER_ALLOWED_TIME,
+ MAX_JOB_COUNT_PER_ALLOWED_TIME);
+ proto.end(qcToken);
+ }
+ }
+
//////////////////////// TESTING HELPERS /////////////////////////////
@VisibleForTesting
@@ -1943,6 +2181,12 @@
return mTimingSessions.get(userId, packageName);
}
+ @VisibleForTesting
+ @NonNull
+ QcConstants getQcConstants() {
+ return mQcConstants;
+ }
+
//////////////////////////// DATA DUMP //////////////////////////////
@Override
@@ -2188,4 +2432,14 @@
proto.end(mToken);
proto.end(token);
}
+
+ @Override
+ public void dumpConstants(IndentingPrintWriter pw) {
+ mQcConstants.dump(pw);
+ }
+
+ @Override
+ public void dumpConstants(ProtoOutputStream proto) {
+ mQcConstants.dump(proto);
+ }
}
diff --git a/services/core/java/com/android/server/job/controllers/StateController.java b/services/core/java/com/android/server/job/controllers/StateController.java
index 74628fb..51be38b 100644
--- a/services/core/java/com/android/server/job/controllers/StateController.java
+++ b/services/core/java/com/android/server/job/controllers/StateController.java
@@ -52,6 +52,13 @@
}
/**
+ * Called when the system boot phase has reached
+ * {@link com.android.server.SystemService#PHASE_SYSTEM_SERVICES_READY}.
+ */
+ public void onSystemServicesReady() {
+ }
+
+ /**
* Implement the logic here to decide whether a job should be tracked by this controller.
* This logic is put here so the JobManager can be completely agnostic of Controller logic.
* Also called when updating a task, so implementing controllers have to be aware of
@@ -127,4 +134,12 @@
Predicate<JobStatus> predicate);
public abstract void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
Predicate<JobStatus> predicate);
+
+ /** Dump any internal constants the Controller may have. */
+ public void dumpConstants(IndentingPrintWriter pw) {
+ }
+
+ /** Dump any internal constants the Controller may have. */
+ public void dumpConstants(ProtoOutputStream proto) {
+ }
}
diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
index 70deb38..ababad9 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -18,13 +18,20 @@
import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AlarmManager;
import android.app.AlarmManager.OnAlarmListener;
+import android.content.ContentResolver;
import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
import android.os.Process;
import android.os.UserHandle;
import android.os.WorkSource;
+import android.provider.Settings;
+import android.util.KeyValueListParser;
import android.util.Log;
import android.util.Slog;
import android.util.TimeUtils;
@@ -32,6 +39,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.job.ConstantsProto;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateControllerProto;
@@ -55,6 +63,9 @@
/** Delay alarm tag for logging purposes */
private final String DELAY_TAG = "*job.delay*";
+ private final Handler mHandler;
+ private final TcConstants mTcConstants;
+
private long mNextJobExpiredElapsedMillis;
private long mNextDelayExpiredElapsedMillis;
@@ -70,6 +81,14 @@
mNextJobExpiredElapsedMillis = Long.MAX_VALUE;
mNextDelayExpiredElapsedMillis = Long.MAX_VALUE;
mChainedAttributionEnabled = mService.isChainedAttributionEnabled();
+
+ mHandler = new Handler(mContext.getMainLooper());
+ mTcConstants = new TcConstants(mHandler);
+ }
+
+ @Override
+ public void onSystemServicesReady() {
+ mTcConstants.start(mContext.getContentResolver());
}
/**
@@ -118,7 +137,7 @@
job.hasDeadlineConstraint() ? job.getLatestRunTimeElapsed() : Long.MAX_VALUE;
final long delayExpiredElapsed =
job.hasTimingDelayConstraint() ? job.getEarliestRunTime() : Long.MAX_VALUE;
- if (mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS) {
+ if (mTcConstants.SKIP_NOT_READY_JOBS) {
if (wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_TIMING_DELAY)) {
maybeUpdateDelayAlarmLocked(delayExpiredElapsed, ws);
}
@@ -148,14 +167,8 @@
}
@Override
- public void onConstantsUpdatedLocked() {
- checkExpiredDeadlinesAndResetAlarm();
- checkExpiredDelaysAndResetAlarm();
- }
-
- @Override
public void evaluateStateLocked(JobStatus job) {
- if (!mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS) {
+ if (!mTcConstants.SKIP_NOT_READY_JOBS) {
return;
}
@@ -248,7 +261,7 @@
}
it.remove();
} else { // Sorted by expiry time, so take the next one and stop.
- if (mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS
+ if (mTcConstants.SKIP_NOT_READY_JOBS
&& !wouldBeReadyWithConstraintLocked(
job, JobStatus.CONSTRAINT_DEADLINE)) {
if (DEBUG) {
@@ -308,7 +321,7 @@
ready = true;
}
} else {
- if (mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS
+ if (mTcConstants.SKIP_NOT_READY_JOBS
&& !wouldBeReadyWithConstraintLocked(
job, JobStatus.CONSTRAINT_TIMING_DELAY)) {
if (DEBUG) {
@@ -439,6 +452,87 @@
}
};
+ @VisibleForTesting
+ void recheckAlarmsLocked() {
+ checkExpiredDeadlinesAndResetAlarm();
+ checkExpiredDelaysAndResetAlarm();
+ }
+
+ @VisibleForTesting
+ class TcConstants extends ContentObserver {
+ private ContentResolver mResolver;
+ private final KeyValueListParser mParser = new KeyValueListParser(',');
+
+ private static final String KEY_SKIP_NOT_READY_JOBS = "skip_not_ready_jobs";
+
+ private static final boolean DEFAULT_SKIP_NOT_READY_JOBS = true;
+
+ /**
+ * Whether or not TimeController should skip setting wakeup alarms for jobs that aren't
+ * ready now.
+ */
+ public boolean SKIP_NOT_READY_JOBS = DEFAULT_SKIP_NOT_READY_JOBS;
+
+ /**
+ * Creates a content observer.
+ *
+ * @param handler The handler to run {@link #onChange} on, or null if none.
+ */
+ TcConstants(Handler handler) {
+ super(handler);
+ }
+
+ private void start(ContentResolver resolver) {
+ mResolver = resolver;
+ mResolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS), false, this);
+ onChange(true, null);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ final String constants = Settings.Global.getString(
+ mResolver, Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS);
+
+ try {
+ mParser.setString(constants);
+ } catch (Exception e) {
+ // Failed to parse the settings string, log this and move on with defaults.
+ Slog.e(TAG, "Bad jobscheduler time controller settings", e);
+ }
+
+ final boolean oldVal = SKIP_NOT_READY_JOBS;
+ SKIP_NOT_READY_JOBS = mParser.getBoolean(
+ KEY_SKIP_NOT_READY_JOBS, DEFAULT_SKIP_NOT_READY_JOBS);
+
+ if (oldVal != SKIP_NOT_READY_JOBS) {
+ synchronized (mLock) {
+ recheckAlarmsLocked();
+ }
+ }
+ }
+
+ private void dump(IndentingPrintWriter pw) {
+ pw.println();
+ pw.println("TimeController:");
+ pw.increaseIndent();
+ pw.printPair(KEY_SKIP_NOT_READY_JOBS, SKIP_NOT_READY_JOBS).println();
+ pw.decreaseIndent();
+ }
+
+ private void dump(ProtoOutputStream proto) {
+ final long tcToken = proto.start(ConstantsProto.TIME_CONTROLLER);
+ proto.write(ConstantsProto.TimeController.SKIP_NOT_READY_JOBS, SKIP_NOT_READY_JOBS);
+ proto.end(tcToken);
+ }
+ }
+
+ @VisibleForTesting
+ @NonNull
+ TcConstants getTcConstants() {
+ return mTcConstants;
+ }
+
@Override
public void dumpControllerStateLocked(IndentingPrintWriter pw,
Predicate<JobStatus> predicate) {
@@ -513,4 +607,14 @@
proto.end(mToken);
proto.end(token);
}
+
+ @Override
+ public void dumpConstants(IndentingPrintWriter pw) {
+ mTcConstants.dump(pw);
+ }
+
+ @Override
+ public void dumpConstants(ProtoOutputStream proto) {
+ mTcConstants.dump(proto);
+ }
}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java
index c739650..1dffcf9 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java
@@ -333,6 +333,7 @@
String[] selectionArguments = new String[] {String.valueOf(userId)};
ensureUserMetadataEntryExists(userId);
+ invalidateKeysForUser(userId);
return db.update(UserMetadataEntry.TABLE_NAME, values, selection, selectionArguments);
}
@@ -394,16 +395,13 @@
/**
* Updates status of old keys to {@code RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE}.
*/
- public void invalidateKeysWithOldGenerationId(int userId, int newGenerationId) {
+ public void invalidateKeysForUser(int userId) {
SQLiteDatabase db = mKeyStoreDbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KeysEntry.COLUMN_NAME_RECOVERY_STATUS,
RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE);
- String selection =
- KeysEntry.COLUMN_NAME_USER_ID + " = ? AND "
- + KeysEntry.COLUMN_NAME_GENERATION_ID + " < ?";
- db.update(KeysEntry.TABLE_NAME, values, selection,
- new String[] {String.valueOf(userId), String.valueOf(newGenerationId)});
+ String selection = KeysEntry.COLUMN_NAME_USER_ID + " = ?";
+ db.update(KeysEntry.TABLE_NAME, values, selection, new String[] {String.valueOf(userId)});
}
/**
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 21a862a..55191db 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1811,14 +1811,15 @@
}
private void registerDeviceConfigChange() {
- DeviceConfig.addOnPropertyChangedListener(
+ DeviceConfig.addOnPropertiesChangedListener(
DeviceConfig.NAMESPACE_SYSTEMUI,
getContext().getMainExecutor(),
- (namespace, name, value) -> {
- if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(namespace)) {
+ (properties) -> {
+ if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(properties.getNamespace())) {
return;
}
- if (SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE.equals(name)) {
+ if (properties.getKeyset()
+ .contains(SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE)) {
mAssistants.resetDefaultAssistantsIfNecessary();
}
});
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 20d47ed..c0f09d2 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -18762,6 +18762,7 @@
boolean installedStateChanged = false;
if (deletedPs != null) {
if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
+ final SparseBooleanArray changedUsers = new SparseBooleanArray();
synchronized (mPackages) {
clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
clearDefaultBrowserIfNeeded(packageName);
@@ -18793,10 +18794,9 @@
}
}
}
+ clearPackagePreferredActivitiesLPw(
+ deletedPs.name, changedUsers, UserHandle.USER_ALL);
}
- final SparseBooleanArray changedUsers = new SparseBooleanArray();
- clearPackagePreferredActivitiesLPw(
- deletedPs.name, changedUsers, UserHandle.USER_ALL);
if (changedUsers.size() > 0) {
updateDefaultHomeNotLocked(changedUsers);
postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index d8f07fe..748a661 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -16,6 +16,7 @@
package com.android.server.rollback;
+import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -32,7 +33,6 @@
import android.os.HandlerThread;
import android.os.PowerManager;
import android.text.TextUtils;
-import android.util.Pair;
import android.util.Slog;
import android.util.StatsLog;
@@ -77,74 +77,50 @@
@Override
public int onHealthCheckFailed(VersionedPackage failedPackage) {
VersionedPackage moduleMetadataPackage = getModuleMetadataPackage();
- if (moduleMetadataPackage == null) {
- // Ignore failure, no mainline update available
- return PackageHealthObserverImpact.USER_IMPACT_NONE;
- }
- if (getAvailableRollback(mContext.getSystemService(RollbackManager.class),
- failedPackage, moduleMetadataPackage) == null) {
+ if (getAvailableRollback(mContext.getSystemService(RollbackManager.class), failedPackage)
+ == null) {
// Don't handle the notification, no rollbacks available for the package
return PackageHealthObserverImpact.USER_IMPACT_NONE;
+ } else {
+ // Rollback is available, we may get a callback into #execute
+ return PackageHealthObserverImpact.USER_IMPACT_MEDIUM;
}
- // Rollback is available, we may get a callback into #execute
- return PackageHealthObserverImpact.USER_IMPACT_MEDIUM;
}
@Override
public boolean execute(VersionedPackage failedPackage) {
- VersionedPackage moduleMetadataPackage = getModuleMetadataPackage();
- if (moduleMetadataPackage == null) {
- // Ignore failure, no mainline update available
- return false;
- }
-
RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
- Pair<RollbackInfo, Boolean> rollbackPair = getAvailableRollback(rollbackManager,
- failedPackage, moduleMetadataPackage);
- if (rollbackPair == null) {
+ VersionedPackage moduleMetadataPackage = getModuleMetadataPackage();
+ RollbackInfo rollback = getAvailableRollback(rollbackManager, failedPackage);
+
+ if (rollback == null) {
Slog.w(TAG, "Expected rollback but no valid rollback found for package: [ "
+ failedPackage.getPackageName() + "] with versionCode: ["
+ failedPackage.getVersionCode() + "]");
return false;
}
- RollbackInfo rollback = rollbackPair.first;
- // We only log mainline package rollbacks, so check if rollback contains the
- // module metadata provider, if it does, the rollback is a mainline rollback
- boolean hasModuleMetadataPackage = rollbackPair.second;
-
- if (hasModuleMetadataPackage) {
- StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE,
- moduleMetadataPackage.getPackageName(),
- moduleMetadataPackage.getVersionCode());
- }
+ logEvent(moduleMetadataPackage,
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE);
LocalIntentReceiver rollbackReceiver = new LocalIntentReceiver((Intent result) -> {
- if (hasModuleMetadataPackage) {
- int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
- RollbackManager.STATUS_FAILURE);
- if (status == RollbackManager.STATUS_SUCCESS) {
- if (rollback.isStaged()) {
- int rollbackId = rollback.getRollbackId();
- BroadcastReceiver listener =
- listenForStagedSessionReady(rollbackManager, rollbackId,
- moduleMetadataPackage);
- handleStagedSessionChange(rollbackManager, rollbackId, listener,
- moduleMetadataPackage);
- } else {
- StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
- StatsLog
- .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
- moduleMetadataPackage.getPackageName(),
- moduleMetadataPackage.getVersionCode());
- }
+ int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
+ RollbackManager.STATUS_FAILURE);
+ if (status == RollbackManager.STATUS_SUCCESS) {
+ if (rollback.isStaged()) {
+ int rollbackId = rollback.getRollbackId();
+ BroadcastReceiver listener =
+ listenForStagedSessionReady(rollbackManager, rollbackId,
+ moduleMetadataPackage);
+ handleStagedSessionChange(rollbackManager, rollbackId, listener,
+ moduleMetadataPackage);
} else {
- StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
- moduleMetadataPackage.getPackageName(),
- moduleMetadataPackage.getVersionCode());
+ logEvent(moduleMetadataPackage,
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS);
}
+ } else {
+ logEvent(moduleMetadataPackage,
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE);
}
});
@@ -193,26 +169,17 @@
}
String moduleMetadataPackageName = getModuleMetadataPackageName();
- if (moduleMetadataPackageName == null) {
- // Only log mainline staged rollbacks
- return;
- }
// Use the version of the metadata package that was installed before
// we rolled back for logging purposes.
VersionedPackage moduleMetadataPackage = null;
for (PackageRollbackInfo packageRollback : rollback.getPackages()) {
- if (moduleMetadataPackageName.equals(packageRollback.getPackageName())) {
+ if (packageRollback.getPackageName().equals(moduleMetadataPackageName)) {
moduleMetadataPackage = packageRollback.getVersionRolledBackFrom();
break;
}
}
- if (moduleMetadataPackage == null) {
- // Only log mainline staged rollbacks
- return;
- }
-
int sessionId = rollback.getCommittedSessionId();
PackageInstaller.SessionInfo sessionInfo = packageInstaller.getSessionInfo(sessionId);
if (sessionInfo == null) {
@@ -220,42 +187,33 @@
return;
}
if (sessionInfo.isStagedSessionApplied()) {
- StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
- moduleMetadataPackage.getPackageName(),
- moduleMetadataPackage.getVersionCode());
+ logEvent(moduleMetadataPackage,
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS);
} else if (sessionInfo.isStagedSessionReady()) {
// TODO: What do for staged session ready but not applied
} else {
- StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
- moduleMetadataPackage.getPackageName(),
- moduleMetadataPackage.getVersionCode());
+ logEvent(moduleMetadataPackage,
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE);
}
}
- private Pair<RollbackInfo, Boolean> getAvailableRollback(RollbackManager rollbackManager,
- VersionedPackage failedPackage, VersionedPackage moduleMetadataPackage) {
+ private RollbackInfo getAvailableRollback(RollbackManager rollbackManager,
+ VersionedPackage failedPackage) {
for (RollbackInfo rollback : rollbackManager.getAvailableRollbacks()) {
- // We only rollback mainline packages, so check if rollback contains the
- // module metadata provider, if it does, the rollback is a mainline rollback
- boolean hasModuleMetadataPackage = false;
- boolean hasFailedPackage = false;
for (PackageRollbackInfo packageRollback : rollback.getPackages()) {
- hasModuleMetadataPackage |= packageRollback.getPackageName().equals(
- moduleMetadataPackage.getPackageName());
- hasFailedPackage |= packageRollback.getPackageName().equals(
+ boolean hasFailedPackage = packageRollback.getPackageName().equals(
failedPackage.getPackageName())
&& packageRollback.getVersionRolledBackFrom().getVersionCode()
== failedPackage.getVersionCode();
- }
- if (hasFailedPackage) {
- return new Pair<RollbackInfo, Boolean>(rollback, hasModuleMetadataPackage);
+ if (hasFailedPackage) {
+ return rollback;
+ }
}
}
return null;
}
+ @Nullable
private String getModuleMetadataPackageName() {
String packageName = mContext.getResources().getString(
R.string.config_defaultModuleMetadataProvider);
@@ -265,6 +223,7 @@
return packageName;
}
+ @Nullable
private VersionedPackage getModuleMetadataPackage() {
String packageName = getModuleMetadataPackageName();
if (packageName == null) {
@@ -311,18 +270,13 @@
if (sessionInfo.isStagedSessionReady()) {
mContext.unregisterReceiver(listener);
saveLastStagedRollbackId(rollbackId);
- StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ logEvent(moduleMetadataPackage,
StatsLog
- .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED,
- moduleMetadataPackage.getPackageName(),
- moduleMetadataPackage.getVersionCode());
+ .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED);
mContext.getSystemService(PowerManager.class).reboot("Rollback staged install");
} else if (sessionInfo.isStagedSessionFailed()) {
- StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
- StatsLog
- .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
- moduleMetadataPackage.getPackageName(),
- moduleMetadataPackage.getVersionCode());
+ logEvent(moduleMetadataPackage,
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE);
mContext.unregisterReceiver(listener);
}
}
@@ -358,4 +312,12 @@
mLastStagedRollbackIdFile.delete();
return rollbackId;
}
+
+ private static void logEvent(@Nullable VersionedPackage moduleMetadataPackage, int type) {
+ Slog.i(TAG, "Watchdog event occurred of type: " + type);
+ if (moduleMetadataPackage != null) {
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED, type,
+ moduleMetadataPackage.getPackageName(), moduleMetadataPackage.getVersionCode());
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 2321898..a3cef7f 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -2432,14 +2432,19 @@
}
}
- private boolean shouldAnimate(int transit) {
+
+ @VisibleForTesting
+ boolean shouldAnimate(int transit) {
final boolean isSplitScreenPrimary =
getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
final boolean allowSplitScreenPrimaryAnimation = transit != TRANSIT_WALLPAPER_OPEN;
- // Don't animate when the task runs recents animation.
+ // Don't animate while the task runs recents animation but only if we are in the mode
+ // where we cancel with deferred screenshot, which means that the controller has
+ // transformed the task.
final RecentsAnimationController controller = mWmService.getRecentsAnimationController();
- if (controller != null && controller.isAnimatingTask(getTask())) {
+ if (controller != null && controller.isAnimatingTask(getTask())
+ && controller.shouldCancelWithDeferredScreenshot()) {
return false;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 78c5dbd..75a8dd5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -481,7 +481,15 @@
public abstract int getTopFocusedDisplayId();
/**
- * Checks whether this display should support showing system decorations.
+ * Checks if this display is configured and allowed to show system decorations.
*/
public abstract boolean shouldShowSystemDecorOnDisplay(int displayId);
+
+ /**
+ * Indicates that the display should show IME.
+ *
+ * @param displayId The id of the display.
+ * @return {@code true} if the display should show IME when an input field become focused on it.
+ */
+ public abstract boolean shouldShowIme(int displayId);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index dae29b2..4eddb30 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -35,6 +35,7 @@
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static android.view.Display.TYPE_VIRTUAL;
import static android.view.WindowManager.DOCKED_INVALID;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
@@ -163,6 +164,7 @@
import android.os.PowerManager.ServiceType;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -6871,10 +6873,21 @@
+ "not exist: " + displayId);
return false;
}
+ final Display display = displayContent.getDisplay();
+ if (isUntrustedVirtualDisplay(display)) {
+ return false;
+ }
return displayContent.supportsSystemDecorations();
}
}
+ /**
+ * @return {@code true} if the display is non-system created virtual display.
+ */
+ private static boolean isUntrustedVirtualDisplay(Display display) {
+ return display.getType() == TYPE_VIRTUAL && display.getOwnerUid() != Process.SYSTEM_UID;
+ }
+
@Override
public void setShouldShowSystemDecors(int displayId, boolean shouldShow) {
if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setShouldShowSystemDecors()")) {
@@ -6908,7 +6921,12 @@
+ displayId);
return false;
}
- return mDisplayWindowSettings.shouldShowImeLocked(displayContent);
+ final Display display = displayContent.getDisplay();
+ if (isUntrustedVirtualDisplay(display)) {
+ return false;
+ }
+ return mDisplayWindowSettings.shouldShowImeLocked(displayContent)
+ || mForceDesktopModeOnExternalDisplays;
}
}
@@ -7352,6 +7370,14 @@
return WindowManagerService.this.shouldShowSystemDecors(displayId);
}
}
+
+ @Override
+ public boolean shouldShowIme(int displayId) {
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ return mDisplayWindowSettings.shouldShowImeLocked(displayContent);
+ }
+ }
}
void registerAppFreezeListener(AppFreezeListener listener) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index 7c30f25..2e7283c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -105,8 +105,9 @@
private static final int SOURCE_USER_ID = 0;
private BroadcastReceiver mChargingReceiver;
- private Constants mConstants;
+ private Constants mJsConstants;
private QuotaController mQuotaController;
+ private QuotaController.QcConstants mQcConstants;
private int mSourceUid;
private IUidObserver mUidObserver;
@@ -132,13 +133,13 @@
.mockStatic(LocalServices.class)
.startMocking();
// Make sure constants turn on QuotaController.
- mConstants = new Constants();
- mConstants.USE_HEARTBEATS = false;
+ mJsConstants = new Constants();
+ mJsConstants.USE_HEARTBEATS = false;
// Called in StateController constructor.
when(mJobSchedulerService.getTestableContext()).thenReturn(mContext);
when(mJobSchedulerService.getLock()).thenReturn(mJobSchedulerService);
- when(mJobSchedulerService.getConstants()).thenReturn(mConstants);
+ when(mJobSchedulerService.getConstants()).thenReturn(mJsConstants);
// Called in QuotaController constructor.
IActivityManager activityManager = ActivityManager.getService();
spyOn(activityManager);
@@ -196,6 +197,7 @@
} catch (RemoteException e) {
fail(e.getMessage());
}
+ mQcConstants = mQuotaController.getQcConstants();
}
@After
@@ -531,7 +533,7 @@
expectedStats.executionTimeInMaxPeriodMs = 22 * MINUTE_IN_MILLIS;
expectedStats.bgJobCountInMaxPeriod = 15;
expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - MINUTE_IN_MILLIS)
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ + mQcConstants.IN_QUOTA_BUFFER_MS;
mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats);
assertEquals(expectedStats, inputStats);
@@ -544,7 +546,7 @@
expectedStats.executionTimeInMaxPeriodMs = 22 * MINUTE_IN_MILLIS;
expectedStats.bgJobCountInMaxPeriod = 15;
expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - MINUTE_IN_MILLIS)
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ + mQcConstants.IN_QUOTA_BUFFER_MS;
mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats);
assertEquals(expectedStats, inputStats);
@@ -557,7 +559,7 @@
expectedStats.executionTimeInMaxPeriodMs = 22 * MINUTE_IN_MILLIS;
expectedStats.bgJobCountInMaxPeriod = 15;
expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - MINUTE_IN_MILLIS)
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ + mQcConstants.IN_QUOTA_BUFFER_MS;
mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats);
assertEquals(expectedStats, inputStats);
@@ -574,7 +576,7 @@
expectedStats.executionTimeInMaxPeriodMs = 23 * MINUTE_IN_MILLIS;
expectedStats.bgJobCountInMaxPeriod = 18;
expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - MINUTE_IN_MILLIS)
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ + mQcConstants.IN_QUOTA_BUFFER_MS;
mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats);
assertEquals(expectedStats, inputStats);
@@ -590,7 +592,7 @@
expectedStats.executionTimeInMaxPeriodMs = 24 * MINUTE_IN_MILLIS;
expectedStats.bgJobCountInMaxPeriod = 20;
expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - MINUTE_IN_MILLIS)
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ + mQcConstants.IN_QUOTA_BUFFER_MS;
mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats);
assertEquals(expectedStats, inputStats);
}
@@ -630,7 +632,7 @@
expectedStats.executionTimeInMaxPeriodMs = 33 * MINUTE_IN_MILLIS;
expectedStats.bgJobCountInMaxPeriod = 20;
expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - 3 * MINUTE_IN_MILLIS)
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ + mQcConstants.IN_QUOTA_BUFFER_MS;
assertEquals(expectedStats,
mQuotaController.getExecutionStatsLocked(0, "com.android.test", WORKING_INDEX));
@@ -642,7 +644,7 @@
expectedStats.executionTimeInMaxPeriodMs = 33 * MINUTE_IN_MILLIS;
expectedStats.bgJobCountInMaxPeriod = 20;
expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - 3 * MINUTE_IN_MILLIS)
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ + mQcConstants.IN_QUOTA_BUFFER_MS;
assertEquals(expectedStats,
mQuotaController.getExecutionStatsLocked(0, "com.android.test", FREQUENT_INDEX));
@@ -654,7 +656,7 @@
expectedStats.executionTimeInMaxPeriodMs = 33 * MINUTE_IN_MILLIS;
expectedStats.bgJobCountInMaxPeriod = 20;
expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - 3 * MINUTE_IN_MILLIS)
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ + mQcConstants.IN_QUOTA_BUFFER_MS;
assertEquals(expectedStats,
mQuotaController.getExecutionStatsLocked(0, "com.android.test", RARE_INDEX));
}
@@ -685,8 +687,8 @@
// Advance clock so that the working stats shouldn't be the same.
advanceElapsedClock(MINUTE_IN_MILLIS);
// Change frequent bucket size so that the stats need to be recalculated.
- mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS = 6 * HOUR_IN_MILLIS;
- mQuotaController.onConstantsUpdatedLocked();
+ mQcConstants.WINDOW_SIZE_FREQUENT_MS = 6 * HOUR_IN_MILLIS;
+ mQcConstants.updateConstants();
ExecutionStats expectedStats = new ExecutionStats();
expectedStats.windowSizeMs = originalStatsActive.windowSizeMs;
@@ -778,7 +780,7 @@
setStandbyBucket(ACTIVE_INDEX);
assertEquals(7 * MINUTE_IN_MILLIS,
mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
- assertEquals(mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS - 9 * MINUTE_IN_MILLIS,
+ assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 9 * MINUTE_IN_MILLIS,
mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
}
@@ -901,7 +903,7 @@
public void testIsWithinQuotaLocked_UnderDuration_OverJobCount() {
setDischarging();
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
- final int jobCount = mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME;
+ final int jobCount = mQcConstants.MAX_JOB_COUNT_PER_ALLOWED_TIME;
mQuotaController.saveTimingSession(0, "com.android.test.spam",
createTimingSession(now - (HOUR_IN_MILLIS), 15 * MINUTE_IN_MILLIS, 25));
mQuotaController.saveTimingSession(0, "com.android.test.spam",
@@ -936,7 +938,7 @@
public void testIsWithinQuotaLocked_OverDuration_OverJobCount() {
setDischarging();
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
- final int jobCount = mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME;
+ final int jobCount = mQcConstants.MAX_JOB_COUNT_PER_ALLOWED_TIME;
mQuotaController.saveTimingSession(0, "com.android.test",
createTimingSession(now - (HOUR_IN_MILLIS), 15 * MINUTE_IN_MILLIS, 25));
mQuotaController.saveTimingSession(0, "com.android.test",
@@ -1098,8 +1100,7 @@
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
// Test with timing sessions out of window but still under max execution limit.
final long expectedAlarmTime =
- (now - 18 * HOUR_IN_MILLIS) + 24 * HOUR_IN_MILLIS
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ (now - 18 * HOUR_IN_MILLIS) + 24 * HOUR_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS;
mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
createTimingSession(now - 18 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, 1));
mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
@@ -1156,8 +1157,7 @@
final long end = now - (2 * HOUR_IN_MILLIS - 5 * MINUTE_IN_MILLIS);
// Counting backwards, the quota will come back one minute before the end.
final long expectedAlarmTime =
- end - MINUTE_IN_MILLIS + 2 * HOUR_IN_MILLIS
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ end - MINUTE_IN_MILLIS + 2 * HOUR_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS;
mQuotaController.saveTimingSession(0, "com.android.test",
new TimingSession(now - 2 * HOUR_IN_MILLIS, end, 1));
mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
@@ -1207,8 +1207,7 @@
// Test with timing sessions in window but still in quota.
final long start = now - (6 * HOUR_IN_MILLIS);
- final long expectedAlarmTime =
- start + 8 * HOUR_IN_MILLIS + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ final long expectedAlarmTime = start + 8 * HOUR_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS;
mQuotaController.saveTimingSession(0, "com.android.test",
createTimingSession(start, 5 * MINUTE_IN_MILLIS, 1));
mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
@@ -1262,7 +1261,7 @@
// needs to be excluded.
final long expectedAlarmTime =
start + MINUTE_IN_MILLIS + 24 * HOUR_IN_MILLIS
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ + mQcConstants.IN_QUOTA_BUFFER_MS;
mQuotaController.saveTimingSession(0, "com.android.test",
createTimingSession(start, 5 * MINUTE_IN_MILLIS, 1));
mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
@@ -1324,21 +1323,21 @@
// And down from there.
final long expectedWorkingAlarmTime =
outOfQuotaTime + (2 * HOUR_IN_MILLIS)
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ + mQcConstants.IN_QUOTA_BUFFER_MS;
mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", WORKING_INDEX);
inOrder.verify(mAlarmManager, times(1))
.set(anyInt(), eq(expectedWorkingAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
final long expectedFrequentAlarmTime =
outOfQuotaTime + (8 * HOUR_IN_MILLIS)
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ + mQcConstants.IN_QUOTA_BUFFER_MS;
mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", FREQUENT_INDEX);
inOrder.verify(mAlarmManager, times(1))
.set(anyInt(), eq(expectedFrequentAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
final long expectedRareAlarmTime =
outOfQuotaTime + (24 * HOUR_IN_MILLIS)
- + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+ + mQcConstants.IN_QUOTA_BUFFER_MS;
mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", RARE_INDEX);
inOrder.verify(mAlarmManager, times(1))
.set(anyInt(), eq(expectedRareAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
@@ -1365,7 +1364,7 @@
ExecutionStats stats = mQuotaController.getExecutionStatsLocked(SOURCE_USER_ID,
SOURCE_PACKAGE, standbyBucket);
stats.jobCountInAllowedTime =
- mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME + 2;
+ mQcConstants.MAX_JOB_COUNT_PER_ALLOWED_TIME + 2;
// Invalid time in the past, so the count shouldn't be used.
stats.jobCountExpirationTimeElapsed =
@@ -1400,8 +1399,8 @@
@Test
public void testMaybeScheduleStartAlarmLocked_SmallRollingQuota_UpdatedBufferSize() {
// Make sure any new value is used correctly.
- mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS *= 2;
- mQuotaController.onConstantsUpdatedLocked();
+ mQcConstants.IN_QUOTA_BUFFER_MS *= 2;
+ mQcConstants.updateConstants();
runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_AllowedTimeCheck();
mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_MaxTimeCheck();
@@ -1410,8 +1409,8 @@
@Test
public void testMaybeScheduleStartAlarmLocked_SmallRollingQuota_UpdatedAllowedTime() {
// Make sure any new value is used correctly.
- mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS /= 2;
- mQuotaController.onConstantsUpdatedLocked();
+ mQcConstants.ALLOWED_TIME_PER_PERIOD_MS /= 2;
+ mQcConstants.updateConstants();
runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_AllowedTimeCheck();
mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_MaxTimeCheck();
@@ -1420,8 +1419,8 @@
@Test
public void testMaybeScheduleStartAlarmLocked_SmallRollingQuota_UpdatedMaxTime() {
// Make sure any new value is used correctly.
- mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS /= 2;
- mQuotaController.onConstantsUpdatedLocked();
+ mQcConstants.MAX_EXECUTION_TIME_MS /= 2;
+ mQcConstants.updateConstants();
runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_AllowedTimeCheck();
mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_MaxTimeCheck();
@@ -1430,10 +1429,10 @@
@Test
public void testMaybeScheduleStartAlarmLocked_SmallRollingQuota_UpdatedEverything() {
// Make sure any new value is used correctly.
- mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS *= 2;
- mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS /= 2;
- mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS /= 2;
- mQuotaController.onConstantsUpdatedLocked();
+ mQcConstants.IN_QUOTA_BUFFER_MS *= 2;
+ mQcConstants.ALLOWED_TIME_PER_PERIOD_MS /= 2;
+ mQcConstants.MAX_EXECUTION_TIME_MS /= 2;
+ mQcConstants.updateConstants();
runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_AllowedTimeCheck();
mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_MaxTimeCheck();
@@ -1448,9 +1447,8 @@
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
// Working set window size is 2 hours.
final int standbyBucket = WORKING_INDEX;
- final long contributionMs = mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS / 2;
- final long remainingTimeMs =
- mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS - contributionMs;
+ final long contributionMs = mQcConstants.IN_QUOTA_BUFFER_MS / 2;
+ final long remainingTimeMs = mQcConstants.ALLOWED_TIME_PER_PERIOD_MS - contributionMs;
// Session straddles edge of bucket window. Only the contribution should be counted towards
// the quota.
@@ -1462,7 +1460,7 @@
// Expected alarm time should be when the app will have QUOTA_BUFFER_MS time of quota, which
// is 2 hours + (QUOTA_BUFFER_MS - contributionMs) after the start of the second session.
final long expectedAlarmTime = now - HOUR_IN_MILLIS + 2 * HOUR_IN_MILLIS
- + (mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS - contributionMs);
+ + (mQcConstants.IN_QUOTA_BUFFER_MS - contributionMs);
mQuotaController.maybeScheduleStartAlarmLocked(SOURCE_USER_ID, SOURCE_PACKAGE,
standbyBucket);
verify(mAlarmManager, times(1))
@@ -1479,9 +1477,8 @@
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
// Working set window size is 2 hours.
final int standbyBucket = WORKING_INDEX;
- final long contributionMs = mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS / 2;
- final long remainingTimeMs =
- mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS - contributionMs;
+ final long contributionMs = mQcConstants.IN_QUOTA_BUFFER_MS / 2;
+ final long remainingTimeMs = mQcConstants.MAX_EXECUTION_TIME_MS - contributionMs;
// Session straddles edge of 24 hour window. Only the contribution should be counted towards
// the quota.
@@ -1493,9 +1490,8 @@
// Expected alarm time should be when the app will have QUOTA_BUFFER_MS time of quota, which
// is 24 hours + (QUOTA_BUFFER_MS - contributionMs) after the start of the second session.
final long expectedAlarmTime = now - 20 * HOUR_IN_MILLIS
- //+ mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS
+ 24 * HOUR_IN_MILLIS
- + (mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS - contributionMs);
+ + (mQcConstants.IN_QUOTA_BUFFER_MS - contributionMs);
mQuotaController.maybeScheduleStartAlarmLocked(SOURCE_USER_ID, SOURCE_PACKAGE,
standbyBucket);
verify(mAlarmManager, times(1))
@@ -1515,12 +1511,12 @@
mQuotaController.maybeStartTrackingJobLocked(jobStatus, null);
assertFalse(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
- mConstants.USE_HEARTBEATS = true;
+ mJsConstants.USE_HEARTBEATS = true;
mQuotaController.onConstantsUpdatedLocked();
Thread.sleep(SECOND_IN_MILLIS); // Job updates are done in the background.
assertTrue(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
- mConstants.USE_HEARTBEATS = false;
+ mJsConstants.USE_HEARTBEATS = false;
mQuotaController.onConstantsUpdatedLocked();
Thread.sleep(SECOND_IN_MILLIS); // Job updates are done in the background.
assertFalse(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
@@ -1528,20 +1524,20 @@
@Test
public void testConstantsUpdating_ValidValues() {
- mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS = 5 * MINUTE_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS = 2 * MINUTE_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS = 15 * MINUTE_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS = 30 * MINUTE_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS = 45 * MINUTE_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS = 60 * MINUTE_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS = 3 * HOUR_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE = 5000;
- mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING = 4000;
- mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT = 3000;
- mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE = 2000;
- mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME = 500;
+ mQcConstants.ALLOWED_TIME_PER_PERIOD_MS = 5 * MINUTE_IN_MILLIS;
+ mQcConstants.IN_QUOTA_BUFFER_MS = 2 * MINUTE_IN_MILLIS;
+ mQcConstants.WINDOW_SIZE_ACTIVE_MS = 15 * MINUTE_IN_MILLIS;
+ mQcConstants.WINDOW_SIZE_WORKING_MS = 30 * MINUTE_IN_MILLIS;
+ mQcConstants.WINDOW_SIZE_FREQUENT_MS = 45 * MINUTE_IN_MILLIS;
+ mQcConstants.WINDOW_SIZE_RARE_MS = 60 * MINUTE_IN_MILLIS;
+ mQcConstants.MAX_EXECUTION_TIME_MS = 3 * HOUR_IN_MILLIS;
+ mQcConstants.MAX_JOB_COUNT_ACTIVE = 5000;
+ mQcConstants.MAX_JOB_COUNT_WORKING = 4000;
+ mQcConstants.MAX_JOB_COUNT_FREQUENT = 3000;
+ mQcConstants.MAX_JOB_COUNT_RARE = 2000;
+ mQcConstants.MAX_JOB_COUNT_PER_ALLOWED_TIME = 500;
- mQuotaController.onConstantsUpdatedLocked();
+ mQcConstants.updateConstants();
assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs());
assertEquals(2 * MINUTE_IN_MILLIS, mQuotaController.getInQuotaBufferMs());
@@ -1561,20 +1557,20 @@
@Test
public void testConstantsUpdating_InvalidValues() {
// Test negatives/too low.
- mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS = -MINUTE_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS = -MINUTE_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS = -MINUTE_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS = -MINUTE_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS = -MINUTE_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS = -MINUTE_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS = -MINUTE_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE = -1;
- mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING = 1;
- mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT = 1;
- mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE = 1;
- mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME = 0;
+ mQcConstants.ALLOWED_TIME_PER_PERIOD_MS = -MINUTE_IN_MILLIS;
+ mQcConstants.IN_QUOTA_BUFFER_MS = -MINUTE_IN_MILLIS;
+ mQcConstants.WINDOW_SIZE_ACTIVE_MS = -MINUTE_IN_MILLIS;
+ mQcConstants.WINDOW_SIZE_WORKING_MS = -MINUTE_IN_MILLIS;
+ mQcConstants.WINDOW_SIZE_FREQUENT_MS = -MINUTE_IN_MILLIS;
+ mQcConstants.WINDOW_SIZE_RARE_MS = -MINUTE_IN_MILLIS;
+ mQcConstants.MAX_EXECUTION_TIME_MS = -MINUTE_IN_MILLIS;
+ mQcConstants.MAX_JOB_COUNT_ACTIVE = -1;
+ mQcConstants.MAX_JOB_COUNT_WORKING = 1;
+ mQcConstants.MAX_JOB_COUNT_FREQUENT = 1;
+ mQcConstants.MAX_JOB_COUNT_RARE = 1;
+ mQcConstants.MAX_JOB_COUNT_PER_ALLOWED_TIME = 0;
- mQuotaController.onConstantsUpdatedLocked();
+ mQcConstants.updateConstants();
assertEquals(MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs());
assertEquals(0, mQuotaController.getInQuotaBufferMs());
@@ -1590,15 +1586,15 @@
assertEquals(100, mQuotaController.getBucketMaxJobCounts()[RARE_INDEX]);
// Test larger than a day. Controller should cap at one day.
- mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS = 25 * HOUR_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS = 25 * HOUR_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS = 25 * HOUR_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS = 25 * HOUR_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS = 25 * HOUR_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS = 25 * HOUR_IN_MILLIS;
- mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS = 25 * HOUR_IN_MILLIS;
+ mQcConstants.ALLOWED_TIME_PER_PERIOD_MS = 25 * HOUR_IN_MILLIS;
+ mQcConstants.IN_QUOTA_BUFFER_MS = 25 * HOUR_IN_MILLIS;
+ mQcConstants.WINDOW_SIZE_ACTIVE_MS = 25 * HOUR_IN_MILLIS;
+ mQcConstants.WINDOW_SIZE_WORKING_MS = 25 * HOUR_IN_MILLIS;
+ mQcConstants.WINDOW_SIZE_FREQUENT_MS = 25 * HOUR_IN_MILLIS;
+ mQcConstants.WINDOW_SIZE_RARE_MS = 25 * HOUR_IN_MILLIS;
+ mQcConstants.MAX_EXECUTION_TIME_MS = 25 * HOUR_IN_MILLIS;
- mQuotaController.onConstantsUpdatedLocked();
+ mQcConstants.updateConstants();
assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs());
assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getInQuotaBufferMs());
@@ -2219,7 +2215,7 @@
verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
// Ran jobs up to the job limit. All of them should be allowed to run.
- for (int i = 0; i < mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME; ++i) {
+ for (int i = 0; i < mQcConstants.MAX_JOB_COUNT_PER_ALLOWED_TIME; ++i) {
JobStatus job = createJobStatus("testStartAlarmScheduled_JobCount_AllowedTime", i);
mQuotaController.maybeStartTrackingJobLocked(job, null);
assertTrue(job.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
@@ -2240,7 +2236,7 @@
ExecutionStats stats = mQuotaController.getExecutionStatsLocked(SOURCE_USER_ID,
SOURCE_PACKAGE, standbyBucket);
final long expectedWorkingAlarmTime =
- stats.jobCountExpirationTimeElapsed + mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS;
+ stats.jobCountExpirationTimeElapsed + mQcConstants.ALLOWED_TIME_PER_PERIOD_MS;
verify(mAlarmManager, times(1))
.set(anyInt(), eq(expectedWorkingAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java
index 494677d..19369db 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java
@@ -39,6 +39,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManagerInternal;
+import android.os.Looper;
import android.os.SystemClock;
import androidx.test.runner.AndroidJUnit4;
@@ -70,7 +71,7 @@
private static final String SOURCE_PACKAGE = "com.android.frameworks.mockingservicestests";
private static final int SOURCE_USER_ID = 0;
- private Constants mConstants;
+ private TimeController.TcConstants mConstants;
private TimeController mTimeController;
private MockitoSession mMockingSession;
@@ -88,14 +89,13 @@
.strictness(Strictness.LENIENT)
.mockStatic(LocalServices.class)
.startMocking();
- // Use default constants for now.
- mConstants = new Constants();
// Called in StateController constructor.
when(mJobSchedulerService.getTestableContext()).thenReturn(mContext);
when(mJobSchedulerService.getLock()).thenReturn(mJobSchedulerService);
- when(mJobSchedulerService.getConstants()).thenReturn(mConstants);
+ when(mJobSchedulerService.getConstants()).thenReturn(mock(Constants.class));
// Called in TimeController constructor.
+ when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
when(mContext.getSystemService(Context.ALARM_SERVICE)).thenReturn(mAlarmManager);
// Used in JobStatus.
doReturn(mock(PackageManagerInternal.class))
@@ -111,6 +111,7 @@
// Initialize real objects.
mTimeController = new TimeController(mJobSchedulerService);
+ mConstants = mTimeController.getTcConstants();
spyOn(mTimeController);
}
@@ -159,7 +160,7 @@
@Test
public void testMaybeStartTrackingJobLocked_DelayInOrder_NoSkipping() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
+ mConstants.SKIP_NOT_READY_JOBS = false;
mTimeController.onConstantsUpdatedLocked();
runTestMaybeStartTrackingJobLocked_DelayInOrder();
@@ -167,7 +168,7 @@
@Test
public void testMaybeStartTrackingJobLocked_DelayInOrder_WithSkipping_AllReady() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+ mConstants.SKIP_NOT_READY_JOBS = true;
mTimeController.onConstantsUpdatedLocked();
doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
@@ -201,7 +202,7 @@
@Test
public void testMaybeStartTrackingJobLocked_DelayInOrder_WithSkipping_SomeNotReady() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+ mConstants.SKIP_NOT_READY_JOBS = true;
mTimeController.onConstantsUpdatedLocked();
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
@@ -235,7 +236,7 @@
@Test
public void testMaybeStartTrackingJobLocked_DelayReverseOrder_NoSkipping() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
+ mConstants.SKIP_NOT_READY_JOBS = false;
mTimeController.onConstantsUpdatedLocked();
runTestMaybeStartTrackingJobLocked_DelayReverseOrder();
@@ -243,7 +244,7 @@
@Test
public void testMaybeStartTrackingJobLocked_DelayReverseOrder_WithSkipping_AllReady() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+ mConstants.SKIP_NOT_READY_JOBS = true;
mTimeController.onConstantsUpdatedLocked();
doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
@@ -279,7 +280,7 @@
@Test
public void testMaybeStartTrackingJobLocked_DelayReverseOrder_WithSkipping_SomeNotReady() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+ mConstants.SKIP_NOT_READY_JOBS = true;
mTimeController.onConstantsUpdatedLocked();
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
@@ -315,7 +316,7 @@
@Test
public void testMaybeStartTrackingJobLocked_DeadlineInOrder_NoSkipping() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
+ mConstants.SKIP_NOT_READY_JOBS = false;
mTimeController.onConstantsUpdatedLocked();
runTestMaybeStartTrackingJobLocked_DeadlineInOrder();
@@ -323,7 +324,7 @@
@Test
public void testMaybeStartTrackingJobLocked_DeadlineInOrder_WithSkipping_AllReady() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+ mConstants.SKIP_NOT_READY_JOBS = true;
mTimeController.onConstantsUpdatedLocked();
doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
@@ -357,7 +358,7 @@
@Test
public void testMaybeStartTrackingJobLocked_DeadlineInOrder_WithSkipping_SomeNotReady() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+ mConstants.SKIP_NOT_READY_JOBS = true;
mTimeController.onConstantsUpdatedLocked();
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
@@ -391,7 +392,7 @@
@Test
public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_NoSkipping() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
+ mConstants.SKIP_NOT_READY_JOBS = false;
mTimeController.onConstantsUpdatedLocked();
runTestMaybeStartTrackingJobLocked_DeadlineReverseOrder();
@@ -399,7 +400,7 @@
@Test
public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_WithSkipping_AllReady() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+ mConstants.SKIP_NOT_READY_JOBS = true;
mTimeController.onConstantsUpdatedLocked();
doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
@@ -438,7 +439,7 @@
@Test
public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_WithSkipping_SomeNotReady() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+ mConstants.SKIP_NOT_READY_JOBS = true;
mTimeController.onConstantsUpdatedLocked();
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
@@ -493,8 +494,8 @@
.wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt());
// Starting off with the skipping off, we should still set an alarm for the earlier job.
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
- mTimeController.onConstantsUpdatedLocked();
+ mConstants.SKIP_NOT_READY_JOBS = false;
+ mTimeController.recheckAlarmsLocked();
InOrder inOrder = inOrder(mAlarmManager);
mTimeController.maybeStartTrackingJobLocked(jobEarliest, null);
@@ -504,16 +505,16 @@
eq(TAG_DEADLINE), any(), any(), any());
// Turn it on, use alarm for later job.
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
- mTimeController.onConstantsUpdatedLocked();
+ mConstants.SKIP_NOT_READY_JOBS = true;
+ mTimeController.recheckAlarmsLocked();
inOrder.verify(mAlarmManager, times(1))
.set(anyInt(), eq(now + HOUR_IN_MILLIS), anyLong(), anyLong(), eq(TAG_DEADLINE),
any(), any(), any());
// Back off, use alarm for earlier job.
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
- mTimeController.onConstantsUpdatedLocked();
+ mConstants.SKIP_NOT_READY_JOBS = false;
+ mTimeController.recheckAlarmsLocked();
inOrder.verify(mAlarmManager, times(1))
.set(anyInt(), eq(now + 5 * MINUTE_IN_MILLIS), anyLong(), anyLong(),
@@ -522,16 +523,16 @@
@Test
public void testCheckExpiredDelaysAndResetAlarm_NoSkipping() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
- mTimeController.onConstantsUpdatedLocked();
+ mConstants.SKIP_NOT_READY_JOBS = false;
+ mTimeController.recheckAlarmsLocked();
runTestCheckExpiredDelaysAndResetAlarm();
}
@Test
public void testCheckExpiredDelaysAndResetAlarm_WithSkipping_AllReady() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
- mTimeController.onConstantsUpdatedLocked();
+ mConstants.SKIP_NOT_READY_JOBS = true;
+ mTimeController.recheckAlarmsLocked();
doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
@@ -589,8 +590,8 @@
@Test
public void testCheckExpiredDelaysAndResetAlarm_WithSkipping_SomeNotReady() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
- mTimeController.onConstantsUpdatedLocked();
+ mConstants.SKIP_NOT_READY_JOBS = true;
+ mTimeController.recheckAlarmsLocked();
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
JobStatus jobLatest = createJobStatus("testCheckExpiredDelaysAndResetAlarm",
@@ -639,16 +640,16 @@
@Test
public void testCheckExpiredDeadlinesAndResetAlarm_NoSkipping() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
- mTimeController.onConstantsUpdatedLocked();
+ mConstants.SKIP_NOT_READY_JOBS = false;
+ mTimeController.recheckAlarmsLocked();
runTestCheckExpiredDeadlinesAndResetAlarm();
}
@Test
public void testCheckExpiredDeadlinesAndResetAlarm_WithSkipping_AllReady() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
- mTimeController.onConstantsUpdatedLocked();
+ mConstants.SKIP_NOT_READY_JOBS = true;
+ mTimeController.recheckAlarmsLocked();
doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
@@ -706,8 +707,8 @@
@Test
public void testCheckExpiredDeadlinesAndResetAlarm_WithSkipping_SomeNotReady() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
- mTimeController.onConstantsUpdatedLocked();
+ mConstants.SKIP_NOT_READY_JOBS = true;
+ mTimeController.recheckAlarmsLocked();
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
JobStatus jobLatest = createJobStatus("testCheckExpiredDeadlinesAndResetAlarm",
@@ -756,8 +757,8 @@
@Test
public void testEvaluateStateLocked_SkippingOff() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
- mTimeController.onConstantsUpdatedLocked();
+ mConstants.SKIP_NOT_READY_JOBS = false;
+ mTimeController.recheckAlarmsLocked();
JobStatus job = createJobStatus("testEvaluateStateLocked_SkippingOff",
createJob().setOverrideDeadline(HOUR_IN_MILLIS));
@@ -768,8 +769,8 @@
@Test
public void testEvaluateStateLocked_SkippingOn_Delay() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
- mTimeController.onConstantsUpdatedLocked();
+ mConstants.SKIP_NOT_READY_JOBS = true;
+ mTimeController.recheckAlarmsLocked();
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
JobStatus jobLatest = createJobStatus("testEvaluateStateLocked_SkippingOn_Delay",
@@ -827,8 +828,8 @@
@Test
public void testEvaluateStateLocked_SkippingOn_Deadline() {
- mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
- mTimeController.onConstantsUpdatedLocked();
+ mConstants.SKIP_NOT_READY_JOBS = true;
+ mTimeController.recheckAlarmsLocked();
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
JobStatus jobLatest = createJobStatus("testEvaluateStateLocked_SkippingOn_Deadline",
diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java
index eb90295..dae3d30 100644
--- a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java
+++ b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java
@@ -137,7 +137,6 @@
return mKeyValueMap.get(getKey(namespace, name));
}).when(() -> DeviceConfig.getProperty(anyString(), anyString()));
-
return new TestWatcher() {
@Override
protected void succeeded(Description description) {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
index bac8414..7a20af4 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
@@ -329,6 +329,31 @@
assertEquals(serialNumber, mRecoverableKeyStoreDb.getUserSerialNumbers().get(userId));
}
+ @Test
+ public void setPlatformKeyGenerationId_invalidatesExistingKeysForUser() {
+ int userId = 42;
+ int generationId = 110;
+ int uid = 1009;
+ int status = 120;
+ String alias = "test";
+ byte[] nonce = getUtf8Bytes("nonce");
+ byte[] keyMaterial = getUtf8Bytes("keymaterial");
+ byte[] keyMetadata = null;
+
+ WrappedKey wrappedKey =
+ new WrappedKey(nonce, keyMaterial, keyMetadata, generationId, status);
+ mRecoverableKeyStoreDb.insertKey(userId, uid, alias, wrappedKey);
+
+ WrappedKey retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias);
+ assertThat(retrievedKey.getRecoveryStatus()).isEqualTo(status);
+
+ mRecoverableKeyStoreDb.setPlatformKeyGenerationId(userId, generationId + 1);
+
+ retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias);
+ assertThat(retrievedKey.getRecoveryStatus())
+ .isEqualTo(RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE);
+ }
+
@Test
public void removeUserFromAllTables_removesData() throws Exception {
@@ -439,7 +464,7 @@
}
@Test
- public void testInvalidateKeysWithOldGenerationId_withSingleKey() {
+ public void testInvalidateKeysForUser_withSingleKey() {
int userId = 12;
int uid = 1009;
int generationId = 6;
@@ -458,7 +483,7 @@
assertThat(retrievedKey.getRecoveryStatus()).isEqualTo(status);
mRecoverableKeyStoreDb.setRecoveryStatus(uid, alias, status2);
- mRecoverableKeyStoreDb.invalidateKeysWithOldGenerationId(userId, generationId + 1);
+ mRecoverableKeyStoreDb.invalidateKeysForUser(userId);
retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias);
assertThat(retrievedKey.getRecoveryStatus())
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 0c2ce61..385748c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -21,6 +21,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
@@ -166,6 +167,25 @@
verify(mAnimationCallbacks).onAnimationFinished(REORDER_KEEP_IN_PLACE, true, false);
}
+ @Test
+ public void testShouldAnimateWhenNoCancelWithDeferredScreenshot() {
+ mWm.setRecentsAnimationController(mController);
+ final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, appWindow, "win1");
+ appWindow.addWindow(win1);
+ assertEquals(appWindow.getTask().getTopVisibleAppToken(), appWindow);
+ assertEquals(appWindow.findMainWindow(), win1);
+
+ mController.addAnimation(appWindow.getTask(), false /* isRecentTaskInvisible */);
+ assertTrue(mController.isAnimatingTask(appWindow.getTask()));
+
+ // Assume appWindow transition should animate when no
+ // IRecentsAnimationController#setCancelWithDeferredScreenshot called.
+ assertFalse(mController.shouldCancelWithDeferredScreenshot());
+ assertTrue(appWindow.shouldAnimate(TRANSIT_ACTIVITY_CLOSE));
+ }
+
private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) {
verify(binder, atLeast(0)).asBinder();
verifyNoMoreInteractions(binder);
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index 12b20ef..64c1830 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -419,7 +419,8 @@
// settings to individually disable the new restrictions for privileged, preloaded
// non-privileged, and non-preinstalled apps.
if (!isIdentifierCheckDisabled() && (
- (!isPreinstalled && !relax3PDeviceIdentifierCheck)
+ (isPrivApp && !relaxPrivDeviceIdentifierCheck)
+ || (!isPreinstalled && !relax3PDeviceIdentifierCheck)
|| (isPreinstalled && !isPrivApp && !relaxNonPrivDeviceIdentifierCheck))) {
// The current package should only be reported in StatsLog if it has not previously been
// reported for the currently invoked device identifier method.
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 13e737e..eb19361 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -18,25 +18,27 @@
import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
-import static com.android.server.PackageWatchdog.MonitoredPackage;
-import static com.android.server.PackageWatchdog.TRIGGER_FAILURE_COUNT;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import android.Manifest;
import android.content.Context;
import android.content.pm.VersionedPackage;
import android.os.Handler;
import android.os.test.TestLooper;
+import android.provider.DeviceConfig;
import android.util.AtomicFile;
import androidx.test.InstrumentationRegistry;
+import com.android.server.PackageWatchdog.MonitoredPackage;
import com.android.server.PackageWatchdog.PackageHealthObserver;
import com.android.server.PackageWatchdog.PackageHealthObserverImpact;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -73,8 +75,13 @@
public void setUp() throws Exception {
new File(InstrumentationRegistry.getContext().getFilesDir(),
"package-watchdog.xml").delete();
+ adoptShellPermissions(Manifest.permission.READ_DEVICE_CONFIG);
mTestLooper = new TestLooper();
- mTestLooper.startAutoDispatch();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ dropShellPermissions();
}
/**
@@ -204,7 +211,7 @@
// Verify random observer not saved returns null
assertNull(watchdog2.getPackages(new TestObserver(OBSERVER_NAME_3)));
- // Then regiser observer1
+ // Then register observer1
watchdog2.registerHealthObserver(observer1);
watchdog2.registerHealthObserver(observer2);
@@ -231,7 +238,7 @@
watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
// Then fail APP_A below the threshold
- for (int i = 0; i < TRIGGER_FAILURE_COUNT - 1; i++) {
+ for (int i = 0; i < watchdog.getTriggerFailureCount() - 1; i++) {
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
}
@@ -258,7 +265,7 @@
watchdog.startObservingHealth(observer1, Arrays.asList(APP_B), SHORT_DURATION);
// Then fail APP_C (not observed) above the threshold
- for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
+ for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_C, VERSION_CODE)));
}
@@ -292,7 +299,7 @@
watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION);
// Then fail APP_A (different version) above the threshold
- for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
+ for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
watchdog.onPackageFailure(Arrays.asList(
new VersionedPackage(APP_A, differentVersionCode)));
}
@@ -331,7 +338,7 @@
SHORT_DURATION);
// Then fail all apps above the threshold
- for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
+ for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE),
new VersionedPackage(APP_B, VERSION_CODE),
new VersionedPackage(APP_C, VERSION_CODE),
@@ -384,7 +391,7 @@
watchdog.startObservingHealth(observerSecond, Arrays.asList(APP_A), LONG_DURATION);
// Then fail APP_A above the threshold
- for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
+ for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
}
// Run handler so package failures are dispatched to observers
@@ -401,7 +408,7 @@
observerSecond.mFailedPackages.clear();
// Then fail APP_A again above the threshold
- for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
+ for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
}
// Run handler so package failures are dispatched to observers
@@ -418,7 +425,7 @@
observerSecond.mFailedPackages.clear();
// Then fail APP_A again above the threshold
- for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
+ for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
}
// Run handler so package failures are dispatched to observers
@@ -435,7 +442,7 @@
observerSecond.mFailedPackages.clear();
// Then fail APP_A again above the threshold
- for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
+ for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
}
// Run handler so package failures are dispatched to observers
@@ -462,7 +469,7 @@
watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
// Then fail APP_A above the threshold
- for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
+ for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
}
@@ -539,6 +546,10 @@
*/
@Test
public void testExplicitHealthCheckStateChanges() throws Exception {
+ adoptShellPermissions(
+ Manifest.permission.WRITE_DEVICE_CONFIG,
+ Manifest.permission.READ_DEVICE_CONFIG);
+
TestController controller = new TestController();
PackageWatchdog watchdog = createWatchdog(controller, true /* withPackagesReady */);
TestObserver observer = new TestObserver(OBSERVER_NAME_1,
@@ -559,7 +570,7 @@
assertEquals(APP_B, requestedPackages.get(1));
// Disable explicit health checks (marks APP_A and APP_B as passed)
- watchdog.setExplicitHealthCheckEnabled(false);
+ setExplicitHealthCheckEnabled(false);
// Run handler so requests/cancellations are dispatched to the controller
mTestLooper.dispatchAll();
@@ -575,7 +586,7 @@
assertEquals(0, observer.mFailedPackages.size());
// Re-enable explicit health checks
- watchdog.setExplicitHealthCheckEnabled(true);
+ setExplicitHealthCheckEnabled(true);
// Run handler so requests/cancellations are dispatched to the controller
mTestLooper.dispatchAll();
@@ -643,11 +654,13 @@
/** Tests {@link MonitoredPackage} health check state transitions. */
@Test
public void testPackageHealthCheckStateTransitions() {
- MonitoredPackage m1 = new MonitoredPackage(APP_A, LONG_DURATION,
+ TestController controller = new TestController();
+ PackageWatchdog wd = createWatchdog(controller, true /* withPackagesReady */);
+ MonitoredPackage m1 = wd.new MonitoredPackage(APP_A, LONG_DURATION,
false /* hasPassedHealthCheck */);
- MonitoredPackage m2 = new MonitoredPackage(APP_B, LONG_DURATION, false);
- MonitoredPackage m3 = new MonitoredPackage(APP_C, LONG_DURATION, false);
- MonitoredPackage m4 = new MonitoredPackage(APP_D, LONG_DURATION, SHORT_DURATION, true);
+ MonitoredPackage m2 = wd.new MonitoredPackage(APP_B, LONG_DURATION, false);
+ MonitoredPackage m3 = wd.new MonitoredPackage(APP_C, LONG_DURATION, false);
+ MonitoredPackage m4 = wd.new MonitoredPackage(APP_D, LONG_DURATION, SHORT_DURATION, true);
// Verify transition: inactive -> active -> passed
// Verify initially inactive
@@ -683,6 +696,32 @@
assertEquals(MonitoredPackage.STATE_PASSED, m4.handleElapsedTimeLocked(LONG_DURATION));
}
+ private void adoptShellPermissions(String... permissions) {
+ InstrumentationRegistry
+ .getInstrumentation()
+ .getUiAutomation()
+ .adoptShellPermissionIdentity(permissions);
+ }
+
+ private void dropShellPermissions() {
+ InstrumentationRegistry
+ .getInstrumentation()
+ .getUiAutomation()
+ .dropShellPermissionIdentity();
+ }
+
+ private void setExplicitHealthCheckEnabled(boolean enabled) {
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
+ PackageWatchdog.PROPERTY_WATCHDOG_EXPLICIT_HEALTH_CHECK_ENABLED,
+ Boolean.toString(enabled), /*makeDefault*/false);
+ //give time for DeviceConfig to broadcast the property value change
+ try {
+ Thread.sleep(SHORT_DURATION);
+ } catch (InterruptedException e) {
+ fail("Thread.sleep unexpectedly failed!");
+ }
+ }
+
private PackageWatchdog createWatchdog() {
return createWatchdog(new TestController(), true /* withPackagesReady */);
}