summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/system-current.txt4
-rw-r--r--cmds/statsd/src/atoms.proto72
-rw-r--r--core/java/android/app/Activity.java2
-rw-r--r--core/java/android/app/ActivityThread.java27
-rw-r--r--core/java/android/app/ClientTransactionHandler.java3
-rw-r--r--core/java/android/app/LocalActivityManager.java2
-rw-r--r--core/java/android/app/servertransaction/NewIntentItem.java21
-rw-r--r--core/java/android/hardware/display/DisplayManagerInternal.java8
-rw-r--r--core/java/android/provider/SearchIndexablesContract.java2
-rw-r--r--core/java/android/provider/SearchIndexablesProvider.java2
-rw-r--r--core/java/android/service/autofill/AutofillService.java2
-rw-r--r--core/java/android/service/autofill/IFillCallback.aidl2
-rw-r--r--core/java/android/util/FeatureFlagUtils.java3
-rw-r--r--core/java/android/util/StatsLog.java8
-rw-r--r--core/java/android/view/SurfaceControl.java16
-rw-r--r--core/java/com/android/internal/infra/AbstractRemoteService.java2
-rw-r--r--core/jni/android_view_SurfaceControl.cpp8
-rw-r--r--core/res/res/values/config.xml3
-rw-r--r--core/res/res/values/strings.xml10
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java6
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java2
-rw-r--r--libs/hwui/renderthread/VulkanSurface.cpp77
-rw-r--r--native/android/system_fonts.cpp3
-rw-r--r--packages/SettingsLib/res/values/strings.xml4
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java25
-rw-r--r--packages/SystemUI/res/values/config.xml4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java123
-rw-r--r--packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java161
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java230
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_sms.xml (renamed from packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_perm_group_sms.xml)0
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_do_not_disturb_on_24dp.xml (renamed from packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_do_not_disturb_24dp.xml)0
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_gray_scale_24dp.xml25
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_sms.xml (renamed from packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_perm_group_sms.xml)0
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_do_not_disturb_on_24dp.xml (renamed from packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_do_not_disturb_24dp.xml)0
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_gray_scale_24dp.xml25
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_sms.xml (renamed from packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_perm_group_sms.xml)0
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_do_not_disturb_on_24dp.xml (renamed from packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_do_not_disturb_24dp.xml)0
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_gray_scale_24dp.xml25
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml5
-rw-r--r--packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml8
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java17
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java14
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java66
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java1
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java3
-rw-r--r--services/core/java/com/android/server/wm/ScreenRotationAnimation.java15
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java21
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl5
-rw-r--r--tests/net/Android.bp1
-rw-r--r--tests/net/common/Android.bp29
-rw-r--r--tests/net/common/java/android/net/IpPrefixTest.java (renamed from tests/net/java/android/net/IpPrefixTest.java)80
-rw-r--r--tools/aapt2/link/TableMerger.cpp32
-rw-r--r--tools/aapt2/link/TableMerger_test.cpp64
57 files changed, 952 insertions, 329 deletions
diff --git a/api/system-current.txt b/api/system-current.txt
index 3ee6a49c1b44..db7521b4ee69 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5980,7 +5980,7 @@ package android.provider {
field public static final String NON_INDEXABLES_KEYS_PATH = "settings/non_indexables_key";
field public static final String PROVIDER_INTERFACE = "android.content.action.SEARCH_INDEXABLES_PROVIDER";
field public static final String SLICE_URI_PAIRS = "slice_uri_pairs";
- field public static final String[] SLICE_URI_PAIRS_COLUMNS;
+ field @NonNull public static final String[] SLICE_URI_PAIRS_COLUMNS;
field public static final String SLICE_URI_PAIRS_PATH = "settings/slice_uri_pairs";
}
@@ -6028,7 +6028,7 @@ package android.provider {
method public android.database.Cursor query(android.net.Uri, String[], String, String[], String);
method public abstract android.database.Cursor queryNonIndexableKeys(String[]);
method public abstract android.database.Cursor queryRawData(String[]);
- method public android.database.Cursor querySliceUriPairs();
+ method @Nullable public android.database.Cursor querySliceUriPairs();
method public abstract android.database.Cursor queryXmlResources(String[]);
method public final int update(android.net.Uri, android.content.ContentValues, String, String[]);
}
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 146cf0cd2da9..e3c2f422a94d 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -159,7 +159,7 @@ message Atom {
BiometricAcquired biometric_acquired = 87;
BiometricAuthenticated biometric_authenticated = 88;
BiometricErrorOccurred biometric_error_occurred = 89;
- Notification notification = 90;
+ // Atom number 90 is available for use.
BatteryHealthSnapshot battery_health_snapshot = 91;
SlowIo slow_io = 92;
BatteryCausedShutdown battery_caused_shutdown = 93;
@@ -3199,76 +3199,6 @@ message BiometricEnrolled {
optional bool success = 4;
}
-message Notification {
-
- // Type of notification event.
- enum Type {
- TYPE_UNKNOWN = 0;
- // Notification became visible to the user.
- TYPE_OPEN = 1;
- // Notification became hidden.
- TYPE_CLOSE = 2;
- // Notification switched to detail mode.
- TYPE_DETAIL = 3;
- // Notification was clicked.
- TYPE_ACTION = 4;
- // Notification was dismissed.
- TYPE_DISMISS = 5;
- // Notification switched to summary mode. The enum value of 14 is to
- // match that of metrics_constants.
- TYPE_COLLAPSE = 14;
- }
- optional Type type = 1;
-
- // Package name associated with the notification.
- optional string package_name = 2;
-
- // Tag associated with notification.
- optional string tag = 3;
-
- // Application-supplied ID associated with the notification.
- optional int32 id = 4;
-
- // Index of notification in the notification panel.
- optional int32 shade_index = 5;
-
- // The number of notifications in the notification panel.
- optional int32 shade_count = 6;
-
- // Importance for the notification.
- optional int32 importance = 7;
-
- // ID for the notification channel.
- optional string channel_id = 8;
-
- // Importance for the notification channel.
- optional int32 channel_importance = 9;
-
- // Application-supplied ID associated with the notifications group.
- optional string group_id = 10;
-
- // Whether notification was a group summary.
- optional bool group_summary = 11;
-
- // Reason for dismissal of a notification. This field is only meaningful for
- // TYPE_DISMISS events.
- optional int32 dismiss_reason = 12;
-
- // The first post time of notification, stable across updates.
- optional int64 creation_millis = 13;
-
- // The most recent interruption time, or the creation time if no updates.
- // Differs from update_millis because updates are filtered based on whether
- // they actually interrupted the user.
- optional int64 interruption_millis = 14;
-
- // The most recent update time, or the creation time if no updates.
- optional int64 update_millis = 15;
-
- // The most recent visibility event.
- optional int64 visible_millis = 16;
-}
-
/*
* Logs when a flag flip update occurrs. Used for mainline modules that update via flag flips.
*/
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 883bcb896841..54fe65db499c 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -820,8 +820,6 @@ public class Activity extends ContextThemeWrapper
/** {@code true} if the activity lifecycle is in a state which supports picture-in-picture.
* This only affects the client-side exception, the actual state check still happens in AMS. */
private boolean mCanEnterPictureInPicture = false;
- /** true if the activity is going through a transient pause */
- /*package*/ boolean mTemporaryPause = false;
/** true if the activity is being destroyed in order to recreate it with a new configuration */
/*package*/ boolean mChangingConfigurations = false;
@UnsupportedAppUsage
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 38006dc5b943..b37d117238af 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -615,7 +615,6 @@ public final class ActivityThread extends ClientTransactionHandler {
sb.append(", finished=").append(activity.isFinishing());
sb.append(", destroyed=").append(activity.isDestroyed());
sb.append(", startedActivity=").append(activity.mStartedActivity);
- sb.append(", temporaryPause=").append(activity.mTemporaryPause);
sb.append(", changingConfigurations=").append(activity.mChangingConfigurations);
sb.append("}");
}
@@ -3319,35 +3318,15 @@ public final class ActivityThread extends ClientTransactionHandler {
}
}
- @UnsupportedAppUsage
- void performNewIntents(IBinder token, List<ReferrerIntent> intents, boolean andPause) {
+ @Override
+ public void handleNewIntent(IBinder token, List<ReferrerIntent> intents) {
final ActivityClientRecord r = mActivities.get(token);
if (r == null) {
return;
}
- final boolean resumed = !r.paused;
- if (resumed) {
- r.activity.mTemporaryPause = true;
- performPauseActivityIfNeeded(r, "performNewIntents");
- }
checkAndBlockForNetworkAccess();
deliverNewIntents(r, intents);
- if (resumed) {
- performResumeActivity(token, false, "performNewIntents");
- r.activity.mTemporaryPause = false;
- } else if (andPause) {
- // In this case the activity was in the paused state when we delivered the intent,
- // to guarantee onResume gets called after onNewIntent we temporarily resume the
- // activity and pause again as the caller wanted.
- performResumeActivity(token, false, "performNewIntents");
- performPauseActivityIfNeeded(r, "performNewIntents");
- }
- }
-
- @Override
- public void handleNewIntent(IBinder token, List<ReferrerIntent> intents, boolean andPause) {
- performNewIntents(token, intents, andPause);
}
public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
@@ -4662,7 +4641,6 @@ public final class ActivityThread extends ClientTransactionHandler {
try {
// Now we are idle.
r.activity.mCalled = false;
- r.activity.mTemporaryPause = true;
mInstrumentation.callActivityOnPause(r.activity);
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
@@ -4684,7 +4662,6 @@ public final class ActivityThread extends ClientTransactionHandler {
deliverResults(r, results, reason);
if (resumed) {
r.activity.performResume(false, reason);
- r.activity.mTemporaryPause = false;
}
}
}
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index 70badfae4a20..9dc8b45a71dc 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -150,8 +150,7 @@ public abstract class ClientTransactionHandler {
Configuration overrideConfig);
/** Deliver new intent. */
- public abstract void handleNewIntent(IBinder token, List<ReferrerIntent> intents,
- boolean andPause);
+ public abstract void handleNewIntent(IBinder token, List<ReferrerIntent> intents);
/** Deliver picture-in-picture mode change notification. */
public abstract void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode,
diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java
index a52fb1a07b84..94b1d7770307 100644
--- a/core/java/android/app/LocalActivityManager.java
+++ b/core/java/android/app/LocalActivityManager.java
@@ -339,7 +339,7 @@ public class LocalActivityManager {
ArrayList<ReferrerIntent> intents = new ArrayList<>(1);
intents.add(new ReferrerIntent(intent, mParent.getPackageName()));
if (localLOGV) Log.v(TAG, r.id + ": new intent");
- mActivityThread.performNewIntents(r, intents, false /* andPause */);
+ mActivityThread.handleNewIntent(r, intents);
r.intent = intent;
moveToState(r, mCurState);
if (mSingleMode) {
diff --git a/core/java/android/app/servertransaction/NewIntentItem.java b/core/java/android/app/servertransaction/NewIntentItem.java
index 4c7f56d4b076..2d1883836d02 100644
--- a/core/java/android/app/servertransaction/NewIntentItem.java
+++ b/core/java/android/app/servertransaction/NewIntentItem.java
@@ -16,6 +16,8 @@
package android.app.servertransaction;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME;
+
import android.annotation.UnsupportedAppUsage;
import android.app.ClientTransactionHandler;
import android.os.IBinder;
@@ -36,19 +38,17 @@ public class NewIntentItem extends ClientTransactionItem {
@UnsupportedAppUsage
private List<ReferrerIntent> mIntents;
- private boolean mPause;
- // TODO(lifecycler): Switch new intent handling to this scheme.
- /*@Override
+ @Override
public int getPostExecutionState() {
return ON_RESUME;
- }*/
+ }
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
- client.handleNewIntent(token, mIntents, mPause);
+ client.handleNewIntent(token, mIntents);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -58,13 +58,12 @@ public class NewIntentItem extends ClientTransactionItem {
private NewIntentItem() {}
/** Obtain an instance initialized with provided params. */
- public static NewIntentItem obtain(List<ReferrerIntent> intents, boolean pause) {
+ public static NewIntentItem obtain(List<ReferrerIntent> intents) {
NewIntentItem instance = ObjectPool.obtain(NewIntentItem.class);
if (instance == null) {
instance = new NewIntentItem();
}
instance.mIntents = intents;
- instance.mPause = pause;
return instance;
}
@@ -72,7 +71,6 @@ public class NewIntentItem extends ClientTransactionItem {
@Override
public void recycle() {
mIntents = null;
- mPause = false;
ObjectPool.recycle(this);
}
@@ -82,13 +80,11 @@ public class NewIntentItem extends ClientTransactionItem {
/** Write to Parcel. */
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeBoolean(mPause);
dest.writeTypedList(mIntents, flags);
}
/** Read from Parcel. */
private NewIntentItem(Parcel in) {
- mPause = in.readBoolean();
mIntents = in.createTypedArrayList(ReferrerIntent.CREATOR);
}
@@ -112,19 +108,18 @@ public class NewIntentItem extends ClientTransactionItem {
return false;
}
final NewIntentItem other = (NewIntentItem) o;
- return mPause == other.mPause && Objects.equals(mIntents, other.mIntents);
+ return Objects.equals(mIntents, other.mIntents);
}
@Override
public int hashCode() {
int result = 17;
- result = 31 * result + (mPause ? 1 : 0);
result = 31 * result + mIntents.hashCode();
return result;
}
@Override
public String toString() {
- return "NewIntentItem{pause=" + mPause + ",intents=" + mIntents + "}";
+ return "NewIntentItem{intents=" + mIntents + "}";
}
}
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 8231985970aa..c9551378c190 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -25,6 +25,7 @@ import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
+import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
/**
@@ -64,13 +65,12 @@ public abstract class DisplayManagerInternal {
public abstract boolean isProximitySensorAvailable();
/**
- * Take a screenshot of the specified display into the provided {@link Surface}.
+ * Take a screenshot of the specified display and return a buffer.
*
* @param displayId The display id to take the screenshot of.
- * @param outSurface The {@link Surface} to take the screenshot into.
- * @return True if the screenshot is taken.
+ * @return The buffer or null if we have failed.
*/
- public abstract boolean screenshot(int displayId, Surface outSurface);
+ public abstract SurfaceControl.ScreenshotGraphicBuffer screenshot(int displayId);
/**
* Returns information about the specified logical display.
diff --git a/core/java/android/provider/SearchIndexablesContract.java b/core/java/android/provider/SearchIndexablesContract.java
index 42c2d5ced806..5f8266d2b579 100644
--- a/core/java/android/provider/SearchIndexablesContract.java
+++ b/core/java/android/provider/SearchIndexablesContract.java
@@ -16,6 +16,7 @@
package android.provider;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.content.ContentResolver;
@@ -210,6 +211,7 @@ public class SearchIndexablesContract {
/**
* Cursor schema for SliceUriPairs.
*/
+ @NonNull
public static final String[] SLICE_URI_PAIRS_COLUMNS = new String[]{
SliceUriPairColumns.KEY,
SliceUriPairColumns.SLICE_URI
diff --git a/core/java/android/provider/SearchIndexablesProvider.java b/core/java/android/provider/SearchIndexablesProvider.java
index d505f02468d0..da29e2e5e39f 100644
--- a/core/java/android/provider/SearchIndexablesProvider.java
+++ b/core/java/android/provider/SearchIndexablesProvider.java
@@ -16,6 +16,7 @@
package android.provider;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.slice.Slice;
import android.content.ContentProvider;
@@ -184,6 +185,7 @@ public abstract class SearchIndexablesProvider extends ContentProvider {
* Returns a {@link Cursor} linking {@link Slice} {@link Uri Uris} to the
* corresponding Settings key.
*/
+ @Nullable
public Cursor querySliceUriPairs() {
// By default no-op;
return null;
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index f39ef9afdb3c..2b7e8b859f28 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -695,6 +695,8 @@ public abstract class AutofillService extends Service {
* finishing the {@link FillCallback}.
*
* @return The history or {@code null} if there are no events.
+ *
+ * @throws RuntimeException if the event history could not be retrieved.
*/
@Nullable public final FillEventHistory getFillEventHistory() {
final AutofillManager afm = getSystemService(AutofillManager.class);
diff --git a/core/java/android/service/autofill/IFillCallback.aidl b/core/java/android/service/autofill/IFillCallback.aidl
index 1bad1d7f474a..32cf712b5fd4 100644
--- a/core/java/android/service/autofill/IFillCallback.aidl
+++ b/core/java/android/service/autofill/IFillCallback.aidl
@@ -25,7 +25,7 @@ import android.service.autofill.FillResponse;
*
* @hide
*/
-interface IFillCallback {
+oneway interface IFillCallback {
void onCancellable(in ICancellationSignal cancellation);
void onSuccess(in FillResponse response);
void onFailure(int requestId, CharSequence message);
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 04046fe066e7..feff9db1a63e 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -42,6 +42,8 @@ public class FeatureFlagUtils {
"settings_global_actions_force_grid_enabled";
public static final String GLOBAL_ACTIONS_PANEL_ENABLED =
"settings_global_actions_panel_enabled";
+ public static final String PIXEL_WALLPAPER_CATEGORY_SWITCH =
+ "settings_pixel_wallpaper_category_switch";
public static final String DYNAMIC_SYSTEM = "settings_dynamic_system";
private static final Map<String, String> DEFAULT_FLAGS;
@@ -60,6 +62,7 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
DEFAULT_FLAGS.put(FORCE_GLOBAL_ACTIONS_GRID_ENABLED, "false");
DEFAULT_FLAGS.put(GLOBAL_ACTIONS_PANEL_ENABLED, "true");
+ DEFAULT_FLAGS.put(PIXEL_WALLPAPER_CATEGORY_SWITCH, "false");
DEFAULT_FLAGS.put("settings_wifi_details_saved_screen", "true");
DEFAULT_FLAGS.put("settings_wifi_details_datausage_header", "false");
}
diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java
index 30d3d7d069b5..dd22a26d61af 100644
--- a/core/java/android/util/StatsLog.java
+++ b/core/java/android/util/StatsLog.java
@@ -136,7 +136,13 @@ public final class StatsLog extends StatsLogInternal {
* @param trainName name of install train.
* @param trainVersionCode version code of the train.
* @param options optional flags about this install.
- * @param state current install state.
+ * The last 3 bits indicate options:
+ * 0x01: FLAG_REQUIRE_STAGING
+ * 0x02: FLAG_ROLLBACK_ENABLED
+ * 0x04: FLAG_REQUIRE_LOW_LATENCY_MONITOR
+ * @param state current install state. Defined as State enums in
+ * BinaryPushStateChanged atom in
+ * frameworks/base/cmds/statsd/src/atoms.proto
* @param experimentIds experiment ids.
* @return True if the log request was sent to statsd.
*/
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index ec62e190d0b4..79363edb0955 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -439,10 +439,13 @@ public final class SurfaceControl implements Parcelable {
public static class ScreenshotGraphicBuffer {
private final GraphicBuffer mGraphicBuffer;
private final ColorSpace mColorSpace;
+ private final boolean mContainsSecureLayers;
- public ScreenshotGraphicBuffer(GraphicBuffer graphicBuffer, ColorSpace colorSpace) {
+ public ScreenshotGraphicBuffer(GraphicBuffer graphicBuffer, ColorSpace colorSpace,
+ boolean containsSecureLayers) {
mGraphicBuffer = graphicBuffer;
mColorSpace = colorSpace;
+ mContainsSecureLayers = containsSecureLayers;
}
/**
@@ -453,13 +456,16 @@ public final class SurfaceControl implements Parcelable {
* @param usage Hint indicating how the buffer will be used
* @param unwrappedNativeObject The native object of GraphicBuffer
* @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named}
+ * @param containsSecureLayer Indicates whether this graphic buffer contains captured contents
+ * of secure layers, in which case the screenshot should not be persisted.
*/
private static ScreenshotGraphicBuffer createFromNative(int width, int height, int format,
- int usage, long unwrappedNativeObject, int namedColorSpace) {
+ int usage, long unwrappedNativeObject, int namedColorSpace,
+ boolean containsSecureLayers) {
GraphicBuffer graphicBuffer = GraphicBuffer.createFromExisting(width, height, format,
usage, unwrappedNativeObject);
ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
- return new ScreenshotGraphicBuffer(graphicBuffer, colorSpace);
+ return new ScreenshotGraphicBuffer(graphicBuffer, colorSpace, containsSecureLayers);
}
public ColorSpace getColorSpace() {
@@ -469,6 +475,10 @@ public final class SurfaceControl implements Parcelable {
public GraphicBuffer getGraphicBuffer() {
return mGraphicBuffer;
}
+
+ public boolean containsSecureLayers() {
+ return mContainsSecureLayers;
+ }
}
/**
diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java
index 1155854efd55..ef5178aca40a 100644
--- a/core/java/com/android/internal/infra/AbstractRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractRemoteService.java
@@ -449,13 +449,13 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
return;
}
mBinding = false;
- mService = getServiceInterface(service);
try {
service.linkToDeath(AbstractRemoteService.this, 0);
} catch (RemoteException re) {
handleBinderDied();
return;
}
+ mService = getServiceInterface(service);
handleOnConnectedStateChangedInternal(true);
mServiceDied = false;
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index c254266961cf..13bcbf6625e2 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -250,10 +250,11 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz,
Rect sourceCrop = rectFromObj(env, sourceCropObj);
sp<GraphicBuffer> buffer;
+ bool capturedSecureLayers = false;
status_t res = ScreenshotClient::capture(displayToken, dataspace,
ui::PixelFormat::RGBA_8888,
sourceCrop, width, height,
- useIdentityTransform, rotation, captureSecureLayers, &buffer);
+ useIdentityTransform, rotation, captureSecureLayers, &buffer, capturedSecureLayers);
if (res != NO_ERROR) {
return NULL;
}
@@ -266,7 +267,8 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz,
buffer->getPixelFormat(),
(jint)buffer->getUsage(),
(jlong)buffer.get(),
- namedColorSpace);
+ namedColorSpace,
+ capturedSecureLayers);
}
static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
@@ -1455,7 +1457,7 @@ int register_android_view_SurfaceControl(JNIEnv* env)
MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
gScreenshotGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env,
screenshotGraphicsBufferClazz,
- "createFromNative", "(IIIIJI)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;");
+ "createFromNative", "(IIIIJIZ)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;");
jclass displayedContentSampleClazz = FindClassOrDie(env,
"android/hardware/display/DisplayedContentSample");
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e8cc96cbd848..0163fc0e20ce 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3345,6 +3345,9 @@
<!-- True if the device supports system decorations on secondary displays. -->
<bool name="config_supportsSystemDecorsOnSecondaryDisplays">true</bool>
+ <!-- True if the device supports insecure lock screen. -->
+ <bool name="config_supportsInsecureLockScreen">true</bool>
+
<!-- True if the device requires AppWidgetService even if it does not have
the PackageManager.FEATURE_APP_WIDGETS feature -->
<bool name="config_enableAppWidgetService">false</bool>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 6f3adfd11a48..256072a23576 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1551,25 +1551,25 @@
<string-array name="face_acquired_vendor">
</string-array>
- <!-- Error message shown when the face hardware can't be accessed. [CHAR LIMIT=50] -->
+ <!-- Error message shown when the face hardware can't be accessed. [CHAR LIMIT=69] -->
<string name="face_error_hw_not_available">Can\u2019t verify face. Hardware not available.</string>
<!-- Error message shown when the face hardware timer has expired and the user needs to restart the operation. [CHAR LIMIT=50] -->
<string name="face_error_timeout">Face timeout reached. Try again.</string>
- <!-- Error message shown when the face hardware has run out of room for storing faces. [CHAR LIMIT=60] -->
+ <!-- Error message shown when the face hardware has run out of room for storing faces. [CHAR LIMIT=69] -->
<string name="face_error_no_space">Can\u2019t store new face data. Delete an old one first.</string>
<!-- Generic error message shown when the face operation (e.g. enrollment or authentication) is canceled. Generally not shown to the user. [CHAR LIMIT=50] -->
<string name="face_error_canceled">Face operation canceled</string>
- <!-- Generic error message shown when the face authentication operation is canceled due to user input. Generally not shown to the user [CHAR LIMIT=50] -->
+ <!-- Generic error message shown when the face authentication operation is canceled due to user input. Generally not shown to the user [CHAR LIMIT=54] -->
<string name="face_error_user_canceled">Face authentication canceled by user</string>
<!-- Generic error message shown when the face operation fails because too many attempts have been made. [CHAR LIMIT=50] -->
<string name="face_error_lockout">Too many attempts. Try again later.</string>
- <!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=60] -->
+ <!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=71] -->
<string name="face_error_lockout_permanent">Too many attempts. Face authentication disabled.</string>
<!-- Generic error message shown when the face hardware can't recognize the face. [CHAR LIMIT=50] -->
<string name="face_error_unable_to_process">Can\u2019t verify face. Try again.</string>
<!-- Generic error message shown when the user has no enrolled face. [CHAR LIMIT=52] -->
<string name="face_error_not_enrolled">You haven\u2019t set up face authentication</string>
- <!-- Generic error message shown when the app requests face authentication on a device without a sensor. [CHAR LIMIT=60] -->
+ <!-- Generic error message shown when the app requests face authentication on a device without a sensor. [CHAR LIMIT=61] -->
<string name="face_error_hw_not_present">Face authentication is not supported on this device</string>
<!-- Template to be used to name enrolled faces by default. [CHAR LIMIT=10] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 664059afd6bc..b87381364b1a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -391,6 +391,7 @@
<java-symbol type="bool" name="config_supportsMultiDisplay" />
<java-symbol type="bool" name="config_noHomeScreen" />
<java-symbol type="bool" name="config_supportsSystemDecorsOnSecondaryDisplays" />
+ <java-symbol type="bool" name="config_supportsInsecureLockScreen" />
<java-symbol type="bool" name="config_guestUserEphemeral" />
<java-symbol type="bool" name="config_localDisplaysMirrorContent" />
<java-symbol type="bool" name="config_localDisplaysPrivate" />
diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
index 447f28e06d7e..5c8bced25108 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
@@ -212,15 +212,15 @@ public class ObjectPoolTests {
@Test
public void testRecycleNewIntentItem() {
- NewIntentItem emptyItem = NewIntentItem.obtain(null, false);
- NewIntentItem item = NewIntentItem.obtain(referrerIntentList(), true);
+ NewIntentItem emptyItem = NewIntentItem.obtain(null);
+ NewIntentItem item = NewIntentItem.obtain(referrerIntentList());
assertNotSame(item, emptyItem);
assertFalse(item.equals(emptyItem));
item.recycle();
assertEquals(item, emptyItem);
- NewIntentItem item2 = NewIntentItem.obtain(referrerIntentList(), true);
+ NewIntentItem item2 = NewIntentItem.obtain(referrerIntentList());
assertSame(item, item2);
assertFalse(item2.equals(emptyItem));
}
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index d117b4096ca0..bffeb2a6c90e 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -128,7 +128,7 @@ public class TransactionParcelTests {
@Test
public void testNewIntent() {
// Write to parcel
- NewIntentItem item = NewIntentItem.obtain(referrerIntentList(), true /* pause */);
+ NewIntentItem item = NewIntentItem.obtain(referrerIntentList());
writeAndPrepareForReading(item);
// Read from parcel and assert
diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp
index 36f540c47973..be78b694f53a 100644
--- a/libs/hwui/renderthread/VulkanSurface.cpp
+++ b/libs/hwui/renderthread/VulkanSurface.cpp
@@ -266,47 +266,46 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode,
vkPixelFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
}
- if (nullptr != vkManager.mGetPhysicalDeviceImageFormatProperties2) {
- VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo;
- externalImageFormatInfo.sType =
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO;
- externalImageFormatInfo.pNext = nullptr;
- externalImageFormatInfo.handleType =
- VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
-
- VkPhysicalDeviceImageFormatInfo2 imageFormatInfo;
- imageFormatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
- imageFormatInfo.pNext = &externalImageFormatInfo;
- imageFormatInfo.format = vkPixelFormat;
- imageFormatInfo.type = VK_IMAGE_TYPE_2D;
- imageFormatInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
- imageFormatInfo.usage = usageFlags;
- imageFormatInfo.flags = 0;
-
- VkAndroidHardwareBufferUsageANDROID hwbUsage;
- hwbUsage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID;
- hwbUsage.pNext = nullptr;
-
- VkImageFormatProperties2 imgFormProps;
- imgFormProps.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
- imgFormProps.pNext = &hwbUsage;
-
- res = vkManager.mGetPhysicalDeviceImageFormatProperties2(vkManager.mPhysicalDevice,
- &imageFormatInfo, &imgFormProps);
- if (VK_SUCCESS != res) {
- ALOGE("Failed to query GetPhysicalDeviceImageFormatProperties2");
- return nullptr;
- }
+ LOG_ALWAYS_FATAL_IF(nullptr == vkManager.mGetPhysicalDeviceImageFormatProperties2,
+ "vkGetPhysicalDeviceImageFormatProperties2 is missing");
+ VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo;
+ externalImageFormatInfo.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO;
+ externalImageFormatInfo.pNext = nullptr;
+ externalImageFormatInfo.handleType =
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
+
+ VkPhysicalDeviceImageFormatInfo2 imageFormatInfo;
+ imageFormatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
+ imageFormatInfo.pNext = &externalImageFormatInfo;
+ imageFormatInfo.format = vkPixelFormat;
+ imageFormatInfo.type = VK_IMAGE_TYPE_2D;
+ imageFormatInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
+ imageFormatInfo.usage = usageFlags;
+ imageFormatInfo.flags = 0;
+
+ VkAndroidHardwareBufferUsageANDROID hwbUsage;
+ hwbUsage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID;
+ hwbUsage.pNext = nullptr;
+
+ VkImageFormatProperties2 imgFormProps;
+ imgFormProps.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
+ imgFormProps.pNext = &hwbUsage;
+
+ res = vkManager.mGetPhysicalDeviceImageFormatProperties2(vkManager.mPhysicalDevice,
+ &imageFormatInfo, &imgFormProps);
+ if (VK_SUCCESS != res) {
+ ALOGE("Failed to query GetPhysicalDeviceImageFormatProperties2");
+ return nullptr;
+ }
- windowInfo.windowUsageFlags = hwbUsage.androidHardwareBufferUsage;
- if (vkManager.isQualcomm()) {
- windowInfo.windowUsageFlags =
- windowInfo.windowUsageFlags | AHARDWAREBUFFER_USAGE_VENDOR_0;
- }
+ uint64_t consumerUsage;
+ native_window_get_consumer_usage(window, &consumerUsage);
+ windowInfo.windowUsageFlags = consumerUsage | hwbUsage.androidHardwareBufferUsage;
- } else {
- ALOGE("VulkanSurface::Create() vkmGetPhysicalDeviceImageFormatProperties2 is missing");
- return nullptr;
+ if (vkManager.isQualcomm()) {
+ windowInfo.windowUsageFlags =
+ windowInfo.windowUsageFlags | AHARDWAREBUFFER_USAGE_VENDOR_0;
}
/*
diff --git a/native/android/system_fonts.cpp b/native/android/system_fonts.cpp
index 302cbd11da4b..9791da63359b 100644
--- a/native/android/system_fonts.cpp
+++ b/native/android/system_fonts.cpp
@@ -250,7 +250,8 @@ AFont* _Nonnull AFontMatcher_match(
minikin::U16StringPiece(text, textLength),
matcher->mFontStyle,
matcher->mLocaleListId,
- static_cast<minikin::FamilyVariant>(matcher->mFamilyVariant));
+ static_cast<minikin::FamilyVariant>(matcher->mFamilyVariant),
+ 1 /* maxRun */);
const minikin::Font* font = runs[0].fakedFont.font;
std::unique_ptr<AFont> result = std::make_unique<AFont>();
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index c6a995cb25f7..8a39b82c0bd9 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -34,6 +34,8 @@
<string name="wifi_security_short_eap" translatable="false">802.1x</string>
<!-- Do not translate. Concise terminology for wifi with WPA3 security -->
<string name="wifi_security_short_sae" translatable="false">WPA3</string>
+ <!-- Do not translate. Concise terminology for wifi with WPA2/WPA3 transition security -->
+ <string name="wifi_security_short_psk_sae" translatable="false">WPA2/WPA3</string>
<!-- Do not translate. Concise terminology for wifi with OWE security -->
<string name="wifi_security_short_owe" translatable="false">OWE</string>
<!-- Do not translate. Concise terminology for wifi with 802.1x EAP Suite-B security -->
@@ -58,6 +60,8 @@
<string name="wifi_security_passpoint" translatable="false">Passpoint</string>
<!-- Do not translate. Terminology for wifi with WPA3 security -->
<string name="wifi_security_sae" translatable="false">WPA3-Personal</string>
+ <!-- Do not translate. Terminology for wifi with WPA2/WPA3 Transition mode security -->
+ <string name="wifi_security_psk_sae" translatable="false">WPA2/WPA3-Personal</string>
<!-- Do not translate. Terminology for wifi with OWE security -->
<string name="wifi_security_owe" translatable="false">Enhanced Open</string>
<!-- Do not translate. Concise terminology for wifi with 802.1x EAP Suite-B security -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 8a88a4c64d0a..1976ec45bf45 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -184,6 +184,7 @@ public class AccessPoint implements Comparable<AccessPoint> {
private static final int PSK_WPA = 1;
private static final int PSK_WPA2 = 2;
private static final int PSK_WPA_WPA2 = 3;
+ private static final int PSK_SAE = 4;
/**
* The number of distinct wifi levels.
@@ -764,7 +765,7 @@ public class AccessPoint implements Comparable<AccessPoint> {
ssid = bestResult.SSID;
bssid = bestResult.BSSID;
security = getSecurity(bestResult);
- if (security == SECURITY_PSK) {
+ if (security == SECURITY_PSK || security == SECURITY_SAE) {
pskType = getPskType(bestResult);
}
mIsCarrierAp = bestResult.isCarrierAp;
@@ -826,8 +827,13 @@ public class AccessPoint implements Comparable<AccessPoint> {
return concise ? context.getString(R.string.wifi_security_short_wep) :
context.getString(R.string.wifi_security_wep);
case SECURITY_SAE:
- return concise ? context.getString(R.string.wifi_security_short_sae) :
- context.getString(R.string.wifi_security_sae);
+ if (pskType == PSK_SAE) {
+ return concise ? context.getString(R.string.wifi_security_short_psk_sae) :
+ context.getString(R.string.wifi_security_psk_sae);
+ } else {
+ return concise ? context.getString(R.string.wifi_security_short_sae) :
+ context.getString(R.string.wifi_security_sae);
+ }
case SECURITY_OWE:
return concise ? context.getString(R.string.wifi_security_short_owe) :
context.getString(R.string.wifi_security_owe);
@@ -1460,15 +1466,22 @@ public class AccessPoint implements Comparable<AccessPoint> {
private static int getPskType(ScanResult result) {
boolean wpa = result.capabilities.contains("WPA-PSK");
- boolean wpa2 = result.capabilities.contains("WPA2-PSK");
- if (wpa2 && wpa) {
+ boolean wpa2 = result.capabilities.contains("RSN-PSK");
+ boolean wpa3TransitionMode = result.capabilities.contains("PSK+SAE");
+ boolean wpa3 = result.capabilities.contains("RSN-SAE");
+ if (wpa3TransitionMode) {
+ return PSK_SAE;
+ } else if (wpa2 && wpa) {
return PSK_WPA_WPA2;
} else if (wpa2) {
return PSK_WPA2;
} else if (wpa) {
return PSK_WPA;
} else {
- Log.w(TAG, "Received abnormal flag string: " + result.capabilities);
+ if (!wpa3) {
+ // Suppress warning for WPA3 only networks
+ Log.w(TAG, "Received abnormal flag string: " + result.capabilities);
+ }
return PSK_UNKNOWN;
}
}
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index ce04638a51e5..a067cd202247 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -316,6 +316,7 @@
<item>com.android.systemui.SliceBroadcastRelayHandler</item>
<item>com.android.systemui.SizeCompatModeActivityController</item>
<item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>
+ <item>com.android.systemui.theme.ThemeOverlayController</item>
</string-array>
<!-- SystemUI vender service, used in config_systemUIServiceComponents. -->
@@ -486,4 +487,7 @@
<integer name="ongoing_appops_dialog_max_apps">5</integer>
+ <!-- Launcher package name for overlaying icons. -->
+ <string name="launcher_overlayable_package" translatable="false">com.android.launcher3</string>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
index 351627980c08..23e2d277034d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
@@ -197,7 +197,7 @@ public class StatusBarWifiView extends FrameLayout implements DarkReceiver,
private boolean updateState(WifiIconState state) {
setContentDescription(state.contentDescription);
if (mState.resId != state.resId && state.resId >= 0) {
- mWifiIcon.setImageDrawable(mContext.getDrawable(mState.resId));
+ mWifiIcon.setImageDrawable(mContext.getDrawable(state.resId));
}
mIn.setVisibility(state.activityIn ? View.VISIBLE : View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
index 212666f24b36..3a6756bb677f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
@@ -204,6 +204,7 @@ public class EdgeBackGestureHandler implements DisplayListener {
if (!mIsEnabled) {
WindowManagerWrapper.getInstance().removePinnedStackListener(mImeChangedListener);
+ mContext.getSystemService(DisplayManager.class).unregisterDisplayListener(this);
try {
WindowManagerGlobal.getWindowManagerService()
@@ -215,6 +216,8 @@ public class EdgeBackGestureHandler implements DisplayListener {
} else {
updateDisplaySize();
+ mContext.getSystemService(DisplayManager.class).registerDisplayListener(this,
+ mContext.getMainThreadHandler());
try {
WindowManagerWrapper.getInstance().addPinnedStackListener(mImeChangedListener);
@@ -344,7 +347,8 @@ public class EdgeBackGestureHandler implements DisplayListener {
private void updateDisplaySize() {
mContext.getSystemService(DisplayManager.class)
- .getDisplay(mDisplayId).getRealSize(mDisplaySize);
+ .getDisplay(mDisplayId)
+ .getRealSize(mDisplaySize);
}
private void sendEvent(int action, int code) {
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
new file mode 100644
index 000000000000..f318f8f94e50
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.theme;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.om.OverlayManager;
+import android.content.pm.UserInfo;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.R;
+import com.android.systemui.SystemUI;
+
+import com.google.android.collect.Sets;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Controls the application of theme overlays across the system for all users.
+ * This service is responsible for:
+ * - Observing changes to Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES and applying the
+ * corresponding overlays across the system
+ * - Observing user switches, applying the overlays for the current user to user 0 (for systemui)
+ * - Observing work profile changes and applying overlays from the primary user to their
+ * associated work profiles
+ */
+public class ThemeOverlayController extends SystemUI {
+ private static final String TAG = "ThemeOverlayController";
+ private static final boolean DEBUG = false;
+
+ private ThemeOverlayManager mThemeManager;
+ private UserManager mUserManager;
+
+ @Override
+ public void start() {
+ if (DEBUG) Log.d(TAG, "Start");
+ mUserManager = mContext.getSystemService(UserManager.class);
+ mThemeManager = new ThemeOverlayManager(
+ mContext.getSystemService(OverlayManager.class),
+ mContext.getString(R.string.launcher_overlayable_package));
+ final Handler bgHandler = Dependency.get(Dependency.BG_HANDLER);
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_USER_SWITCHED);
+ filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
+ mContext.registerReceiverAsUser(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (DEBUG) Log.d(TAG, "Updating overlays for user switch / profile added.");
+ updateThemeOverlays();
+ }
+ }, UserHandle.ALL, filter, null, bgHandler);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES),
+ false,
+ new ContentObserver(bgHandler) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ if (DEBUG) Log.d(TAG, "Overlay changed for user: " + userId);
+ if (ActivityManager.getCurrentUser() == userId) {
+ updateThemeOverlays();
+ }
+ }
+ },
+ UserHandle.USER_ALL);
+ }
+
+ private void updateThemeOverlays() {
+ final int currentUser = ActivityManager.getCurrentUser();
+ final String overlayPackageJson = Settings.Secure.getStringForUser(
+ mContext.getContentResolver(), Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
+ currentUser);
+ if (DEBUG) Log.d(TAG, "updateThemeOverlays: " + overlayPackageJson);
+ final Map<String, String> categoryToPackage = new ArrayMap<>();
+ if (!TextUtils.isEmpty(overlayPackageJson)) {
+ try {
+ JSONObject object = new JSONObject(overlayPackageJson);
+ for (String category : ThemeOverlayManager.THEME_CATEGORIES) {
+ if (object.has(category)) {
+ categoryToPackage.put(category, object.getString(category));
+ }
+ }
+ } catch (JSONException e) {
+ Log.i(TAG, "Failed to parse THEME_CUSTOMIZATION_OVERLAY_PACKAGES.", e);
+ }
+ }
+ Set<UserHandle> userHandles = Sets.newHashSet(UserHandle.of(currentUser));
+ for (UserInfo userInfo : mUserManager.getEnabledProfiles(currentUser)) {
+ if (userInfo.isManagedProfile()) {
+ userHandles.add(userInfo.getUserHandle());
+ }
+ }
+ mThemeManager.applyCurrentUserOverlays(categoryToPackage, userHandles);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
new file mode 100644
index 000000000000..1a9fd5315c32
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.theme;
+
+import android.content.om.OverlayInfo;
+import android.content.om.OverlayManager;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.google.android.collect.Sets;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+class ThemeOverlayManager {
+ private static final String TAG = "ThemeOverlayManager";
+ private static final boolean DEBUG = false;
+
+ @VisibleForTesting
+ static final String ANDROID_PACKAGE = "android";
+ @VisibleForTesting
+ static final String SETTINGS_PACKAGE = "com.android.settings";
+ @VisibleForTesting
+ static final String SYSUI_PACKAGE = "com.android.systemui";
+
+ @VisibleForTesting
+ static final String OVERLAY_CATEGORY_COLOR = "android.theme.customization.accent_color";
+ @VisibleForTesting
+ static final String OVERLAY_CATEGORY_FONT = "android.theme.customization.font";
+ @VisibleForTesting
+ static final String OVERLAY_CATEGORY_SHAPE =
+ "android.theme.customization.adaptive_icon_shape";
+ @VisibleForTesting
+ static final String OVERLAY_CATEGORY_ICON_ANDROID =
+ "android.theme.customization.icon_pack.android";
+ @VisibleForTesting
+ static final String OVERLAY_CATEGORY_ICON_SYSUI =
+ "android.theme.customization.icon_pack.systemui";
+ @VisibleForTesting
+ static final String OVERLAY_CATEGORY_ICON_SETTINGS =
+ "android.theme.customization.icon_pack.settings";
+ @VisibleForTesting
+ static final String OVERLAY_CATEGORY_ICON_LAUNCHER =
+ "android.theme.customization.icon_pack.launcher";
+
+ /* All theme customization categories used by the system. */
+ static final Set<String> THEME_CATEGORIES = Sets.newHashSet(
+ OVERLAY_CATEGORY_COLOR,
+ OVERLAY_CATEGORY_FONT,
+ OVERLAY_CATEGORY_SHAPE,
+ OVERLAY_CATEGORY_ICON_ANDROID,
+ OVERLAY_CATEGORY_ICON_SYSUI,
+ OVERLAY_CATEGORY_ICON_SETTINGS,
+ OVERLAY_CATEGORY_ICON_LAUNCHER);
+
+ /* Categories that need to applied to the current user as well as the system user. */
+ @VisibleForTesting
+ static final Set<String> SYSTEM_USER_CATEGORIES = Sets.newHashSet(
+ OVERLAY_CATEGORY_COLOR,
+ OVERLAY_CATEGORY_FONT,
+ OVERLAY_CATEGORY_SHAPE,
+ OVERLAY_CATEGORY_ICON_ANDROID,
+ OVERLAY_CATEGORY_ICON_SYSUI);
+
+ /* Allowed overlay categories for each target package. */
+ private final Map<String, Set<String>> mTargetPackageToCategories = new ArrayMap<>();
+ /* Target package for each overlay category. */
+ private final Map<String, String> mCategoryToTargetPackage = new ArrayMap<>();
+ private final OverlayManager mOverlayManager;
+ private final String mLauncherPackage;
+
+ ThemeOverlayManager(OverlayManager overlayManager, String launcherPackage) {
+ mOverlayManager = overlayManager;
+ mLauncherPackage = launcherPackage;
+ mTargetPackageToCategories.put(ANDROID_PACKAGE, Sets.newHashSet(
+ OVERLAY_CATEGORY_COLOR, OVERLAY_CATEGORY_FONT,
+ OVERLAY_CATEGORY_SHAPE, OVERLAY_CATEGORY_ICON_ANDROID));
+ mTargetPackageToCategories.put(SYSUI_PACKAGE,
+ Sets.newHashSet(OVERLAY_CATEGORY_ICON_SYSUI));
+ mTargetPackageToCategories.put(SETTINGS_PACKAGE,
+ Sets.newHashSet(OVERLAY_CATEGORY_ICON_SETTINGS));
+ mTargetPackageToCategories.put(mLauncherPackage,
+ Sets.newHashSet(OVERLAY_CATEGORY_ICON_LAUNCHER));
+ mCategoryToTargetPackage.put(OVERLAY_CATEGORY_COLOR, ANDROID_PACKAGE);
+ mCategoryToTargetPackage.put(OVERLAY_CATEGORY_FONT, ANDROID_PACKAGE);
+ mCategoryToTargetPackage.put(OVERLAY_CATEGORY_SHAPE, ANDROID_PACKAGE);
+ mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ICON_ANDROID, ANDROID_PACKAGE);
+ mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ICON_SYSUI, SYSUI_PACKAGE);
+ mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ICON_SETTINGS, SETTINGS_PACKAGE);
+ mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ICON_LAUNCHER, mLauncherPackage);
+ }
+
+ /**
+ * Apply the set of overlay packages to the set of {@code UserHandle}s provided. Overlays that
+ * affect sysui will also be applied to the system user.
+ */
+ void applyCurrentUserOverlays(
+ Map<String, String> categoryToPackage, Set<UserHandle> userHandles) {
+ final Map<Boolean, List<String>> categorySplit = THEME_CATEGORIES.stream().collect(
+ Collectors.partitioningBy((category) -> categoryToPackage.containsKey(category)));
+ final List<String> overlayCategoriesToEnable = categorySplit.get(true);
+ final List<String> overlayCategoriesToDisable = categorySplit.get(false);
+
+ // Disable all overlays that have not been specified in the user setting.
+ final List<OverlayInfo> overlays = new ArrayList<>();
+ overlayCategoriesToDisable.stream()
+ .map(category -> mCategoryToTargetPackage.get(category))
+ .collect(Collectors.toSet())
+ .forEach(targetPackage -> overlays.addAll(mOverlayManager
+ .getOverlayInfosForTarget(targetPackage, UserHandle.SYSTEM)));
+ overlays.stream()
+ .filter(o ->
+ mTargetPackageToCategories.get(o.targetPackageName).contains(o.category))
+ .filter(o -> overlayCategoriesToDisable.contains(o.category))
+ .filter(o -> o.isEnabled())
+ .forEach(o -> setEnabled(o.packageName, o.category, userHandles, false));
+
+
+ // Enable all overlays specified in the user setting.
+ overlayCategoriesToEnable.forEach((category) ->
+ setEnabled(categoryToPackage.get(category), category, userHandles, true));
+ }
+
+ private void setEnabled(
+ String packageName, String category, Set<UserHandle> handles, boolean enabled) {
+ for (UserHandle userHandle : handles) {
+ setEnabled(packageName, userHandle, enabled);
+ }
+ if (!handles.contains(UserHandle.SYSTEM) && SYSTEM_USER_CATEGORIES.contains(category)) {
+ setEnabled(packageName, UserHandle.SYSTEM, enabled);
+ }
+ }
+
+ private void setEnabled(String pkg, UserHandle userHandle, boolean enabled) {
+ if (DEBUG) Log.d(TAG, String.format("setEnabled: %s %s %b", pkg, userHandle, enabled));
+ if (enabled) {
+ mOverlayManager.setEnabledExclusiveInCategory(pkg, userHandle);
+ } else {
+ mOverlayManager.setEnabled(pkg, false, userHandle);
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java
new file mode 100644
index 000000000000..da039a403087
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.theme;
+
+import static com.android.systemui.theme.ThemeOverlayManager.ANDROID_PACKAGE;
+import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_COLOR;
+import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_FONT;
+import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_ICON_ANDROID;
+import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_ICON_LAUNCHER;
+import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_ICON_SETTINGS;
+import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_ICON_SYSUI;
+import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_SHAPE;
+import static com.android.systemui.theme.ThemeOverlayManager.SETTINGS_PACKAGE;
+import static com.android.systemui.theme.ThemeOverlayManager.SYSTEM_USER_CATEGORIES;
+import static com.android.systemui.theme.ThemeOverlayManager.SYSUI_PACKAGE;
+import static com.android.systemui.theme.ThemeOverlayManager.THEME_CATEGORIES;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.om.OverlayInfo;
+import android.content.om.OverlayManager;
+import android.os.UserHandle;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+
+import com.google.android.collect.Maps;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class ThemeOverlayManagerTest extends SysuiTestCase {
+ private static final String TEST_DISABLED_PREFIX = "com.example.";
+ private static final String TEST_ENABLED_PREFIX = "com.example.enabled.";
+
+ private static final Map<String, String> ALL_CATEGORIES_MAP = Maps.newArrayMap();
+
+ static {
+ for (String category : THEME_CATEGORIES) {
+ ALL_CATEGORIES_MAP.put(category, TEST_DISABLED_PREFIX + category);
+ }
+ }
+
+ private static final String LAUNCHER_PACKAGE = "com.android.launcher3";
+ private static final UserHandle TEST_USER = UserHandle.of(5);
+ private static final Set<UserHandle> TEST_USER_HANDLES = Sets.newHashSet(TEST_USER);
+
+ @Mock
+ OverlayManager mOverlayManager;
+
+ private ThemeOverlayManager mManager;
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mManager = new ThemeOverlayManager(mOverlayManager, LAUNCHER_PACKAGE);
+ when(mOverlayManager.getOverlayInfosForTarget(ANDROID_PACKAGE, UserHandle.SYSTEM))
+ .thenReturn(Lists.newArrayList(
+ createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_COLOR,
+ ANDROID_PACKAGE, OVERLAY_CATEGORY_COLOR, false),
+ createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_FONT,
+ ANDROID_PACKAGE, OVERLAY_CATEGORY_FONT, false),
+ createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_SHAPE,
+ ANDROID_PACKAGE, OVERLAY_CATEGORY_SHAPE, false),
+ createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ICON_ANDROID,
+ ANDROID_PACKAGE, OVERLAY_CATEGORY_ICON_ANDROID, false),
+ createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_COLOR,
+ ANDROID_PACKAGE, OVERLAY_CATEGORY_COLOR, true),
+ createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_FONT,
+ ANDROID_PACKAGE, OVERLAY_CATEGORY_FONT, true),
+ createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_SHAPE,
+ ANDROID_PACKAGE, OVERLAY_CATEGORY_SHAPE, true),
+ createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_ANDROID,
+ ANDROID_PACKAGE, OVERLAY_CATEGORY_ICON_ANDROID, true)));
+ when(mOverlayManager.getOverlayInfosForTarget(SYSUI_PACKAGE, UserHandle.SYSTEM))
+ .thenReturn(Lists.newArrayList(
+ createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ICON_SYSUI,
+ SYSUI_PACKAGE, OVERLAY_CATEGORY_ICON_SYSUI, false),
+ createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_SYSUI,
+ SYSUI_PACKAGE, OVERLAY_CATEGORY_ICON_SYSUI, true)));
+ when(mOverlayManager.getOverlayInfosForTarget(SETTINGS_PACKAGE, UserHandle.SYSTEM))
+ .thenReturn(Lists.newArrayList(
+ createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ICON_SETTINGS,
+ SETTINGS_PACKAGE, OVERLAY_CATEGORY_ICON_SETTINGS, false),
+ createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_SETTINGS,
+ SETTINGS_PACKAGE, OVERLAY_CATEGORY_ICON_SETTINGS, true)));
+ when(mOverlayManager.getOverlayInfosForTarget(LAUNCHER_PACKAGE, UserHandle.SYSTEM))
+ .thenReturn(Lists.newArrayList(
+ createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ICON_LAUNCHER,
+ LAUNCHER_PACKAGE, OVERLAY_CATEGORY_ICON_LAUNCHER, false),
+ createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_LAUNCHER,
+ LAUNCHER_PACKAGE, OVERLAY_CATEGORY_ICON_LAUNCHER, true)));
+ }
+
+ @Test
+ public void allCategoriesSpecified_allEnabledExclusively() {
+ mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES);
+
+ for (String overlayPackage : ALL_CATEGORIES_MAP.values()) {
+ verify(mOverlayManager).setEnabledExclusiveInCategory(overlayPackage, TEST_USER);
+ }
+ }
+
+ @Test
+ public void allCategoriesSpecified_sysuiCategoriesAlsoAppliedToSysuiUser() {
+ mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES);
+
+ for (Map.Entry<String, String> entry : ALL_CATEGORIES_MAP.entrySet()) {
+ if (SYSTEM_USER_CATEGORIES.contains(entry.getKey())) {
+ verify(mOverlayManager).setEnabledExclusiveInCategory(
+ entry.getValue(), UserHandle.SYSTEM);
+ } else {
+ verify(mOverlayManager, never()).setEnabledExclusiveInCategory(
+ entry.getValue(), UserHandle.SYSTEM);
+ }
+ }
+ }
+
+ @Test
+ public void allCategoriesSpecified_enabledForAllUserHandles() {
+ Set<UserHandle> userHandles = Sets.newHashSet(TEST_USER_HANDLES);
+ UserHandle newUserHandle = UserHandle.of(10);
+ userHandles.add(newUserHandle);
+ mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, userHandles);
+
+ for (String overlayPackage : ALL_CATEGORIES_MAP.values()) {
+ verify(mOverlayManager).setEnabledExclusiveInCategory(overlayPackage, TEST_USER);
+ verify(mOverlayManager).setEnabledExclusiveInCategory(overlayPackage, newUserHandle);
+ }
+ }
+
+ @Test
+ public void allCategoriesSpecified_overlayManagerNotQueried() {
+ mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES);
+
+ verify(mOverlayManager, never())
+ .getOverlayInfosForTarget(anyString(), any(UserHandle.class));
+ }
+
+ @Test
+ public void someCategoriesSpecified_specifiedEnabled_unspecifiedDisabled() {
+ Map<String, String> categoryToPackage = new HashMap<>(ALL_CATEGORIES_MAP);
+ categoryToPackage.remove(OVERLAY_CATEGORY_ICON_SETTINGS);
+ categoryToPackage.remove(OVERLAY_CATEGORY_ICON_ANDROID);
+
+ mManager.applyCurrentUserOverlays(categoryToPackage, TEST_USER_HANDLES);
+
+ for (String overlayPackage : categoryToPackage.values()) {
+ verify(mOverlayManager).setEnabledExclusiveInCategory(overlayPackage, TEST_USER);
+ }
+ verify(mOverlayManager).setEnabled(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_SETTINGS,
+ false, TEST_USER);
+ verify(mOverlayManager).setEnabled(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_ANDROID,
+ false, TEST_USER);
+ }
+
+ @Test
+ public void zeroCategoriesSpecified_allDisabled() {
+ mManager.applyCurrentUserOverlays(Maps.newArrayMap(), TEST_USER_HANDLES);
+
+ for (String category : THEME_CATEGORIES) {
+ verify(mOverlayManager).setEnabled(TEST_ENABLED_PREFIX + category, false, TEST_USER);
+ }
+ }
+
+ @Test
+ public void nonThemeCategorySpecified_ignored() {
+ Map<String, String> categoryToPackage = new HashMap<>(ALL_CATEGORIES_MAP);
+ categoryToPackage.put("blah.category", "com.example.blah.category");
+
+ mManager.applyCurrentUserOverlays(categoryToPackage, TEST_USER_HANDLES);
+
+ verify(mOverlayManager, never()).setEnabled("com.example.blah.category", false, TEST_USER);
+ verify(mOverlayManager, never()).setEnabledExclusiveInCategory("com.example.blah.category",
+ TEST_USER);
+ }
+
+ @Test
+ public void overlayManagerOnlyQueriedForUnspecifiedPackages() {
+ Map<String, String> categoryToPackage = new HashMap<>(ALL_CATEGORIES_MAP);
+ categoryToPackage.remove(OVERLAY_CATEGORY_ICON_SETTINGS);
+
+ mManager.applyCurrentUserOverlays(categoryToPackage, TEST_USER_HANDLES);
+
+ verify(mOverlayManager).getOverlayInfosForTarget(SETTINGS_PACKAGE, UserHandle.SYSTEM);
+ verify(mOverlayManager, never()).getOverlayInfosForTarget(ANDROID_PACKAGE,
+ UserHandle.SYSTEM);
+ verify(mOverlayManager, never()).getOverlayInfosForTarget(SYSUI_PACKAGE, UserHandle.SYSTEM);
+ verify(mOverlayManager, never()).getOverlayInfosForTarget(LAUNCHER_PACKAGE,
+ UserHandle.SYSTEM);
+ }
+
+ private static OverlayInfo createOverlayInfo(String packageName, String targetPackageName,
+ String category, boolean enabled) {
+ return new OverlayInfo(packageName, targetPackageName, null, category, "",
+ enabled ? OverlayInfo.STATE_ENABLED : OverlayInfo.STATE_DISABLED, 0, 0, false);
+ }
+}
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_perm_group_sms.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_sms.xml
index d15cfa3b1e3a..d15cfa3b1e3a 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_perm_group_sms.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_sms.xml
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_do_not_disturb_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_do_not_disturb_on_24dp.xml
index 87d82e58cd67..87d82e58cd67 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_do_not_disturb_24dp.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_do_not_disturb_on_24dp.xml
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_gray_scale_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_gray_scale_24dp.xml
new file mode 100644
index 000000000000..4e5497a76991
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_gray_scale_24dp.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10c5.52,0,10-4.48,10-10S17.52,2,12,2z M12,17v-1.5h7.74 c-0.24,0.53-0.54,1.03-0.88,1.5H12z M12,14v-1.5h8.47c-0.03,0.51-0.1,1.01-0.22,1.5H12z M12,11V9.5h8.12 c0.15,0.48,0.25,0.99,0.31,1.5H12z M12,8V6.5h6.47c0.39,0.46,0.74,0.96,1.03,1.5H12z M16.81,5H12V3.5C13.79,3.5,15.44,4.06,16.81,5 z M3.5,12c0-4.17,3.03-7.65,7-8.36v16.72C6.53,19.65,3.5,16.17,3.5,12z M12,18.5h5.47c-1.48,1.25-3.39,2-5.47,2V18.5z" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_perm_group_sms.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_sms.xml
index eef9e62f15b0..eef9e62f15b0 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_perm_group_sms.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_sms.xml
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_do_not_disturb_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_do_not_disturb_on_24dp.xml
index b4baf231d1b6..b4baf231d1b6 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_do_not_disturb_24dp.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_do_not_disturb_on_24dp.xml
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_gray_scale_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_gray_scale_24dp.xml
new file mode 100644
index 000000000000..6b5903c569c0
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_gray_scale_24dp.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M11,19.93C7.06,19.44,4,16.08,4,12 c0-4.08,3.05-7.44,7-7.93V19.93z M13,4.07C14.03,4.2,15,4.52,15.87,5H13V4.07z M13,7h5.24c0.25,0.31,0.48,0.65,0.68,1H13V7z M13,19.93V19h2.87C15,19.48,14.03,19.8,13,19.93z M18.24,17H13v-1h5.92C18.72,16.35,18.49,16.69,18.24,17z M19.74,14H13v-1h6.93 C19.89,13.34,19.82,13.67,19.74,14z M19.93,11H13v-1h6.74C19.82,10.33,19.89,10.66,19.93,11z" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_perm_group_sms.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_sms.xml
index b5509d12a059..b5509d12a059 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_perm_group_sms.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_sms.xml
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_do_not_disturb_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_do_not_disturb_on_24dp.xml
index 5f704f0ed828..5f704f0ed828 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_do_not_disturb_24dp.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_do_not_disturb_on_24dp.xml
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_gray_scale_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_gray_scale_24dp.xml
new file mode 100644
index 000000000000..308c2ab34563
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_gray_scale_24dp.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10c5.52,0,10-4.48,10-10S17.52,2,12,2z M12,12.5h8.47c-0.03,0.51-0.1,1.01-0.22,1.5 H12V12.5z M12,11V9.5h8.12c0.15,0.48,0.25,0.99,0.31,1.5H12z M12,8V6.5h6.47c0.39,0.46,0.74,0.96,1.03,1.5H12z M16.81,5H12V3.5 C13.79,3.5,15.44,4.06,16.81,5z M3.5,12c0-4.17,3.03-7.65,7-8.36v16.72C6.53,19.65,3.5,16.17,3.5,12z M12,18.5h5.47 c-1.48,1.25-3.39,2-5.47,2V18.5z M18.86,17H12v-1.5h7.74C19.5,16.03,19.2,16.53,18.86,17z" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml
index 2e2ea085f396..2e662684438f 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml
@@ -21,5 +21,8 @@
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M20.49,11.26h-1.03c-0.15-1.51-0.74-2.88-1.65-3.99l0.73-0.73c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0L16.75,6.2 c-1.11-0.91-2.49-1.51-4-1.66V3.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.04c-1.5,0.15-2.88,0.75-3.99,1.65L6.53,5.46 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L6.2,7.25c-0.91,1.11-1.51,2.49-1.66,3.99H3.51c-0.41,0-0.75,0.34-0.75,0.75 s0.34,0.75,0.75,0.75h1.03c0.15,1.51,0.74,2.88,1.65,3.99l-0.73,0.73c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22l0.73-0.73c1.11,0.91,2.48,1.51,3.98,1.66v1.02c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.02 c1.48-0.14,2.86-0.71,4.01-1.65l0.73,0.73c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 l-0.72-0.72c0.94-1.14,1.51-2.52,1.66-4h1.03c0.41,0,0.75-0.34,0.75-0.75S20.9,11.26,20.49,11.26z M12,18c-3.31,0-6-2.69-6-6 s2.69-6,6-6s6,2.69,6,6S15.31,18,12,18z" />
+ android:pathData="M21.25,11.25h-2.8A6.46,6.46,0,0,0,17.09,8l2-2A0.75 0.75 ,0,0,0,18,4.93l-2,2a6.46,6.46,0,0,0-3.28-1.36V2.75a0.75 0.75 ,0,0,0-1.5,0v2.8A6.46,6.46,0,0,0,8,6.91l-2-2A0.75 0.75 ,0,0,0,4.93,6l2,2a6.46,6.46,0,0,0-1.36,3.28H2.75a0.75 0.75 ,0,0,0,0,1.5h2.8A6.46,6.46,0,0,0,6.91,16l-2,2A0.75 0.75 ,0,0,0,6,19.07l2-2a6.46,6.46,0,0,0,3.28,1.36v2.8a0.75 0.75 ,0,0,0,1.5,0v-2.8A6.46,6.46,0,0,0,16,17.09l2,2A0.75 0.75 ,0,0,0,19.07,18l-2-2a6.46,6.46,0,0,0,1.36-3.28h2.8a0.75 0.75 ,0,0,0,0-1.5ZM12,17a5,5,0,1,1,5-5A5,5,0,0,1,12,17Z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,15.5a3.5,3.5,0,0,0,0-7Z" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
index 2e4665e59f1e..697d1c29eac7 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
@@ -20,9 +20,9 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="?android:attr/colorControlActivated"
- android:pathData="M22.46,11.25h-3.02c-0.15-1.51-0.75-2.88-1.66-4l2.17-2.17c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0l-2.18,2.18 c-1.11-0.91-2.49-1.51-3.99-1.66V1.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v3.04c-1.5,0.15-2.88,0.75-3.99,1.65 L5.06,4.01C4.77,3.71,4.29,3.71,4,4.01S3.71,4.77,4,5.07l2.18,2.18c-0.91,1.11-1.51,2.48-1.66,3.98H1.48 c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h3.04c0.15,1.51,0.74,2.88,1.65,3.99L3.99,18.9c-0.29,0.29-0.29,0.77,0,1.06 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22l2.17-2.17c1.11,0.91,2.49,1.52,3.99,1.67v3.02c0,0.41,0.34,0.75,0.75,0.75 s0.75-0.34,0.75-0.75v-3.02c1.48-0.14,2.86-0.71,4.01-1.65l2.16,2.16c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 c0.29-0.29,0.29-0.77,0-1.06l-2.16-2.16c0.94-1.15,1.52-2.53,1.66-4.01h3.02c0.41,0,0.75-0.34,0.75-0.75S22.88,11.25,22.46,11.25z M12,18c-3.31,0-6-2.69-6-6s2.69-6,6-6s6,2.69,6,6S15.31,18,12,18z" />
- <path
android:fillColor="?android:attr/colorPrimary"
- android:pathData="M 12 6 C 15.313708499 6 18 8.68629150102 18 12 C 18 15.313708499 15.313708499 18 12 18 C 8.68629150102 18 6 15.313708499 6 12 C 6 8.68629150102 8.68629150102 6 12 6 Z" />
+ android:pathData="M 12 0 L 12 0 Q 24 0 24 12 L 24 12 Q 24 24 12 24 L 12 24 Q 0 24 0 12 L 0 12 Q 0 0 12 0 Z" />
+ <path
+ android:fillColor="?android:attr/colorControlActivated"
+ android:pathData="M21.25,11.25h-2.8A6.46,6.46,0,0,0,17.09,8l2-2A0.75 0.75 ,0,0,0,18,4.93l-2,2a6.46,6.46,0,0,0-3.28-1.36V2.75a0.75 0.75 ,0,0,0-1.5,0v2.8A6.46,6.46,0,0,0,8,6.91l-2-2A0.75 0.75 ,0,0,0,4.93,6l2,2a6.46,6.46,0,0,0-1.36,3.28H2.75a0.75 0.75 ,0,0,0,0,1.5h2.8A6.46,6.46,0,0,0,6.91,16l-2,2A0.75 0.75 ,0,0,0,6,19.07l2-2a6.46,6.46,0,0,0,3.28,1.36v2.8a0.75 0.75 ,0,0,0,1.5,0v-2.8A6.46,6.46,0,0,0,16,17.09l2,2A0.75 0.75 ,0,0,0,19.07,18l-2-2a6.46,6.46,0,0,0,1.36-3.28h2.8a0.75 0.75 ,0,0,0,0-1.5ZM12,17a5,5,0,1,1,5-5A5,5,0,0,1,12,17Z" />
</vector> \ No newline at end of file
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 3010324488b8..3abd0ba29871 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1269,21 +1269,14 @@ public final class DisplayManagerService extends SystemService {
return null;
}
- private boolean screenshotInternal(int displayId, Surface outSurface) {
+ private SurfaceControl.ScreenshotGraphicBuffer screenshotInternal(int displayId) {
final IBinder token = getDisplayToken(displayId);
if (token == null) {
- return false;
+ return null;
}
- final SurfaceControl.ScreenshotGraphicBuffer gb =
- SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
+ return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
token, new Rect(), 0 /* width */, 0 /* height */,
false /* useIdentityTransform */, 0 /* rotation */);
- try {
- outSurface.attachAndQueueBuffer(gb.getGraphicBuffer());
- } catch (RuntimeException e) {
- Slog.w(TAG, "Failed to take screenshot - " + e.getMessage());
- }
- return true;
}
@VisibleForTesting
@@ -2354,8 +2347,8 @@ public final class DisplayManagerService extends SystemService {
}
@Override
- public boolean screenshot(int displayId, Surface outSurface) {
- return screenshotInternal(displayId, outSurface);
+ public SurfaceControl.ScreenshotGraphicBuffer screenshot(int displayId) {
+ return screenshotInternal(displayId);
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 51bf5191247f..1ce9d827d80f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3051,7 +3051,7 @@ public class PackageManagerService extends IPackageManager.Stub
+ mSdkVersion + "; regranting permissions for internal storage");
}
mPermissionManager.updateAllPermissions(
- StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, false, mPackages.values(),
+ StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
mPermissionCallback);
ver.sdkVersion = mSdkVersion;
@@ -5569,7 +5569,7 @@ public class PackageManagerService extends IPackageManager.Stub
synchronized (mPackages) {
mPermissionManager.updateAllPermissions(
- StorageManager.UUID_PRIVATE_INTERNAL, false, false, mPackages.values(),
+ StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
mPermissionCallback);
for (int userId : UserManagerService.getInstance().getUserIds()) {
final int packageCount = mPackages.size();
@@ -21222,8 +21222,8 @@ public class PackageManagerService extends IPackageManager.Stub
// try optimizing this.
synchronized (mPackages) {
mPermissionManager.updateAllPermissions(
- StorageManager.UUID_PRIVATE_INTERNAL, false, mIsPreQUpgrade,
- mPackages.values(), mPermissionCallback);
+ StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
+ mPermissionCallback);
}
// Watch for external volumes that come and go over time
@@ -22213,8 +22213,8 @@ public class PackageManagerService extends IPackageManager.Stub
logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
+ mSdkVersion + "; regranting permissions for " + volumeUuid);
}
- mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated, false,
- mPackages.values(), mPermissionCallback);
+ mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated, mPackages.values(),
+ mPermissionCallback);
// Yay, everything is now upgraded
ver.forceCurrent();
@@ -23247,7 +23247,7 @@ public class PackageManagerService extends IPackageManager.Stub
synchronized(mPackages) {
// NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
mPermissionManager.updateAllPermissions(
- StorageManager.UUID_PRIVATE_INTERNAL, true, false, mPackages.values(),
+ StorageManager.UUID_PRIVATE_INTERNAL, true, mPackages.values(),
mPermissionCallback);
}
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 9336c55d4a79..c75a462d5bc1 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -34,10 +34,10 @@ import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQU
import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
-import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
+import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
import static android.content.pm.PackageManager.RESTRICTED_PERMISSIONS_ENABLED;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.os.UserHandle.getAppId;
@@ -69,7 +69,6 @@ import android.content.pm.PermissionInfo;
import android.metrics.LogMaker;
import android.os.Binder;
import android.os.Build;
-import android.os.Debug;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
@@ -82,7 +81,6 @@ import android.os.storage.StorageManagerInternal;
import android.permission.PermissionControllerManager;
import android.permission.PermissionManager;
import android.permission.PermissionManagerInternal;
-import android.provider.Settings;
import android.permission.PermissionManagerInternal.OnRuntimePermissionStateChangedListener;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -2458,9 +2456,8 @@ public class PermissionManagerService {
}
if (updatePermissions) {
- // Update app permissions to take into account the new whitelist state.
- updatePermissions(pkg.packageName, pkg, getVolumeUuidForPackage(pkg),
- 0 /*flags*/, null /*allPackages*/, callback);
+ // Update permission of this app to take into account the new whitelist state.
+ restorePermissionState(pkg, false, pkg.packageName, callback);
// If this resulted in losing a permission we need to kill the app.
if (oldGrantedRestrictedPermissions != null) {
@@ -2605,62 +2602,12 @@ public class PermissionManagerService {
}
private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
- boolean updatePermissionsOnPreQUpdate, Collection<PackageParser.Package> allPackages,
- PermissionCallback callback) {
+ Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
final int flags = UPDATE_PERMISSIONS_ALL |
(sdkUpdated
? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
: 0);
updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
-
- if (updatePermissionsOnPreQUpdate) {
- final int[] userIds = UserManagerService.getInstance().getUserIds();
-
- for (PackageParser.Package pkg : allPackages) {
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
- if (ps == null) {
- return;
- }
-
- final boolean appSupportsRuntimePermissions =
- pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
- final PermissionsState permsState = ps.getPermissionsState();
-
- for (String permName : new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_BACKGROUND_LOCATION}) {
- final BasePermission bp = mSettings.getPermissionLocked(permName);
-
- for (int userId : userIds) {
- if (Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.LOCATION_PERMISSIONS_UPGRADE_TO_Q_MODE, 0, userId)
- != 0) {
- continue;
- }
-
- final PermissionState permState = permsState.getRuntimePermissionState(
- permName, userId);
-
- if (permState != null
- && (permState.getFlags() & BLOCKING_PERMISSION_FLAGS) == 0) {
- if (permState.isGranted()) {
- permsState.updatePermissionFlags(bp, userId,
- USER_PERMISSION_FLAGS, 0);
- }
-
- if (appSupportsRuntimePermissions) {
- permsState.revokeRuntimePermission(bp, userId);
- } else {
- // Force a review even for apps that were already installed
- permsState.updatePermissionFlags(bp, userId,
- FLAG_PERMISSION_REVIEW_REQUIRED,
- FLAG_PERMISSION_REVIEW_REQUIRED);
- }
- }
- }
- }
- }
- }
}
private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
@@ -3150,10 +3097,9 @@ public class PermissionManagerService {
}
@Override
public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
- boolean updatePermissionsOnPreQUpdate, Collection<PackageParser.Package> allPackages,
- PermissionCallback callback) {
+ Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
PermissionManagerService.this.updateAllPermissions(
- volumeUuid, sdkUpdated, updatePermissionsOnPreQUpdate, allPackages, callback);
+ volumeUuid, sdkUpdated, allPackages, callback);
}
@Override
public String[] getAppOpPermissionPackages(String permName) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index 34f922e11d08..9fb71f44716b 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -93,7 +93,6 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
@Nullable PackageParser.Package pkg, boolean replaceGrant,
@NonNull Collection<PackageParser.Package> allPacakges, PermissionCallback callback);
public abstract void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdate,
- boolean updatePermissionsOnPreQUpdate,
@NonNull Collection<PackageParser.Package> allPacakges, PermissionCallback callback);
/**
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 91ec4a083ed9..6ac41baefa4a 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1595,8 +1595,8 @@ final class ActivityRecord extends ConfigurationContainer {
try {
ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
ar.add(rintent);
- mAtmService.getLifecycleManager().scheduleTransaction(
- app.getThread(), appToken, NewIntentItem.obtain(ar, mState == PAUSED));
+ mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
+ NewIntentItem.obtain(ar));
unsent = false;
} catch (RemoteException e) {
Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 6bc9fc8a9f7c..e0890a6fe17f 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -2962,8 +2962,7 @@ class ActivityStack extends ConfigurationContainer {
}
if (next.newIntents != null) {
- transaction.addCallback(NewIntentItem.obtain(next.newIntents,
- false /* andPause */));
+ transaction.addCallback(NewIntentItem.obtain(next.newIntents));
}
// Well the app will no longer be stopped.
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 2d5c97f9a3a5..b90d60227be4 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -275,7 +275,20 @@ class ScreenRotationAnimation {
final int displayId = display.getDisplayId();
final Surface surface = mService.mSurfaceFactory.make();
surface.copyFrom(mSurfaceControl);
- if (mService.mDisplayManagerInternal.screenshot(displayId, surface)) {
+ SurfaceControl.ScreenshotGraphicBuffer gb =
+ mService.mDisplayManagerInternal.screenshot(displayId);
+ if (gb != null) {
+ try {
+ surface.attachAndQueueBuffer(gb.getGraphicBuffer());
+ } catch (RuntimeException e) {
+ Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage());
+ }
+ // If the screenshot contains secure layers, we have to make sure the
+ // screenshot surface we display it in also has FLAG_SECURE so that
+ // the user can not screenshot secure layers via the screenshot surface.
+ if (gb.containsSecureLayers()) {
+ t.setSecure(mSurfaceControl, true);
+ }
t.setLayer(mSurfaceControl, SCREEN_FREEZE_LAYER_SCREENSHOT);
t.setAlpha(mSurfaceControl, 0);
t.show(mSurfaceControl);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 072eb88797f8..9c63a82b5673 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -8954,6 +8954,27 @@ public class TelephonyManager {
return retval;
}
+ /**
+ * Determines the {@link PhoneAccountHandle} associated with a subscription Id.
+ *
+ * @param subscriptionId The subscription Id to check.
+ * @return The {@link PhoneAccountHandle} associated with a subscription Id, or {@code null} if
+ * there is no associated {@link PhoneAccountHandle}.
+ * @hide
+ */
+ public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
+ PhoneAccountHandle returnValue = null;
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ returnValue = service.getPhoneAccountHandleForSubscriptionId(subscriptionId);
+ }
+ } catch (RemoteException e) {
+ }
+
+ return returnValue;
+ }
+
private int getSubIdForPhoneAccountHandle(PhoneAccountHandle phoneAccountHandle) {
int retval = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
try {
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index c8cd2495bdd9..ecbbd6a6c786 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1265,6 +1265,11 @@ interface ITelephony {
*/
int getSubIdForPhoneAccount(in PhoneAccount phoneAccount);
+ /**
+ * Returns the PhoneAccountHandle associated with a subscription ID.
+ */
+ PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId);
+
void factoryReset(int subId);
/**
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index 70b408949dea..c8ef82ec9acc 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -4,6 +4,7 @@
java_defaults {
name: "FrameworksNetTests-jni-defaults",
static_libs: [
+ "FrameworksNetCommonTests",
"frameworks-base-testutils",
"framework-protos",
"androidx.test.rules",
diff --git a/tests/net/common/Android.bp b/tests/net/common/Android.bp
new file mode 100644
index 000000000000..0a1ac75aac80
--- /dev/null
+++ b/tests/net/common/Android.bp
@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Tests in this folder are included both in unit tests and CTS.
+// They must be fast and stable, and exercise public or test APIs.
+java_library {
+ name: "FrameworksNetCommonTests",
+ srcs: ["java/**/*.java"],
+ static_libs: [
+ "androidx.test.rules",
+ "junit",
+ ],
+ libs: [
+ "android.test.base.stubs",
+ ],
+} \ No newline at end of file
diff --git a/tests/net/java/android/net/IpPrefixTest.java b/tests/net/common/java/android/net/IpPrefixTest.java
index abf019afed44..719960d48604 100644
--- a/tests/net/java/android/net/IpPrefixTest.java
+++ b/tests/net/common/java/android/net/IpPrefixTest.java
@@ -39,7 +39,7 @@ import java.util.Random;
@SmallTest
public class IpPrefixTest {
- private static InetAddress Address(String addr) {
+ private static InetAddress address(String addr) {
return InetAddress.parseNumericAddress(addr);
}
@@ -58,59 +58,59 @@ public class IpPrefixTest {
try {
p = new IpPrefix((byte[]) null, 9);
fail("Expected NullPointerException: null byte array");
- } catch(RuntimeException expected) {}
+ } catch (RuntimeException expected) { }
try {
p = new IpPrefix((InetAddress) null, 10);
fail("Expected NullPointerException: null InetAddress");
- } catch(RuntimeException expected) {}
+ } catch (RuntimeException expected) { }
try {
p = new IpPrefix((String) null);
fail("Expected NullPointerException: null String");
- } catch(RuntimeException expected) {}
+ } catch (RuntimeException expected) { }
try {
byte[] b2 = {1, 2, 3, 4, 5};
p = new IpPrefix(b2, 29);
fail("Expected IllegalArgumentException: invalid array length");
- } catch(IllegalArgumentException expected) {}
+ } catch (IllegalArgumentException expected) { }
try {
p = new IpPrefix("1.2.3.4");
fail("Expected IllegalArgumentException: no prefix length");
- } catch(IllegalArgumentException expected) {}
+ } catch (IllegalArgumentException expected) { }
try {
p = new IpPrefix("1.2.3.4/");
fail("Expected IllegalArgumentException: empty prefix length");
- } catch(IllegalArgumentException expected) {}
+ } catch (IllegalArgumentException expected) { }
try {
p = new IpPrefix("foo/32");
fail("Expected IllegalArgumentException: invalid address");
- } catch(IllegalArgumentException expected) {}
+ } catch (IllegalArgumentException expected) { }
try {
p = new IpPrefix("1/32");
fail("Expected IllegalArgumentException: deprecated IPv4 format");
- } catch(IllegalArgumentException expected) {}
+ } catch (IllegalArgumentException expected) { }
try {
p = new IpPrefix("1.2.3.256/32");
fail("Expected IllegalArgumentException: invalid IPv4 address");
- } catch(IllegalArgumentException expected) {}
+ } catch (IllegalArgumentException expected) { }
try {
p = new IpPrefix("foo/32");
fail("Expected IllegalArgumentException: non-address");
- } catch(IllegalArgumentException expected) {}
+ } catch (IllegalArgumentException expected) { }
try {
p = new IpPrefix("f00:::/32");
fail("Expected IllegalArgumentException: invalid IPv6 address");
- } catch(IllegalArgumentException expected) {}
+ } catch (IllegalArgumentException expected) { }
}
@Test
@@ -132,17 +132,17 @@ public class IpPrefixTest {
try {
p = new IpPrefix(IPV4_BYTES, 33);
fail("Expected IllegalArgumentException: invalid prefix length");
- } catch(RuntimeException expected) {}
+ } catch (RuntimeException expected) { }
try {
p = new IpPrefix(IPV4_BYTES, 128);
fail("Expected IllegalArgumentException: invalid prefix length");
- } catch(RuntimeException expected) {}
+ } catch (RuntimeException expected) { }
try {
p = new IpPrefix(IPV4_BYTES, -1);
fail("Expected IllegalArgumentException: negative prefix length");
- } catch(RuntimeException expected) {}
+ } catch (RuntimeException expected) { }
p = new IpPrefix(IPV6_BYTES, 128);
assertEquals("2001:db8:dead:beef:f00::a0/128", p.toString());
@@ -162,12 +162,12 @@ public class IpPrefixTest {
try {
p = new IpPrefix(IPV6_BYTES, -1);
fail("Expected IllegalArgumentException: negative prefix length");
- } catch(RuntimeException expected) {}
+ } catch (RuntimeException expected) { }
try {
p = new IpPrefix(IPV6_BYTES, 129);
fail("Expected IllegalArgumentException: negative prefix length");
- } catch(RuntimeException expected) {}
+ } catch (RuntimeException expected) { }
}
@@ -226,28 +226,28 @@ public class IpPrefixTest {
@Test
public void testContainsInetAddress() {
IpPrefix p = new IpPrefix("2001:db8:f00::ace:d00d/127");
- assertTrue(p.contains(Address("2001:db8:f00::ace:d00c")));
- assertTrue(p.contains(Address("2001:db8:f00::ace:d00d")));
- assertFalse(p.contains(Address("2001:db8:f00::ace:d00e")));
- assertFalse(p.contains(Address("2001:db8:f00::bad:d00d")));
- assertFalse(p.contains(Address("2001:4868:4860::8888")));
- assertFalse(p.contains(Address("8.8.8.8")));
+ assertTrue(p.contains(address("2001:db8:f00::ace:d00c")));
+ assertTrue(p.contains(address("2001:db8:f00::ace:d00d")));
+ assertFalse(p.contains(address("2001:db8:f00::ace:d00e")));
+ assertFalse(p.contains(address("2001:db8:f00::bad:d00d")));
+ assertFalse(p.contains(address("2001:4868:4860::8888")));
+ assertFalse(p.contains(address("8.8.8.8")));
p = new IpPrefix("192.0.2.0/23");
- assertTrue(p.contains(Address("192.0.2.43")));
- assertTrue(p.contains(Address("192.0.3.21")));
- assertFalse(p.contains(Address("192.0.0.21")));
- assertFalse(p.contains(Address("8.8.8.8")));
- assertFalse(p.contains(Address("2001:4868:4860::8888")));
+ assertTrue(p.contains(address("192.0.2.43")));
+ assertTrue(p.contains(address("192.0.3.21")));
+ assertFalse(p.contains(address("192.0.0.21")));
+ assertFalse(p.contains(address("8.8.8.8")));
+ assertFalse(p.contains(address("2001:4868:4860::8888")));
IpPrefix ipv6Default = new IpPrefix("::/0");
- assertTrue(ipv6Default.contains(Address("2001:db8::f00")));
- assertFalse(ipv6Default.contains(Address("192.0.2.1")));
+ assertTrue(ipv6Default.contains(address("2001:db8::f00")));
+ assertFalse(ipv6Default.contains(address("192.0.2.1")));
IpPrefix ipv4Default = new IpPrefix("0.0.0.0/0");
- assertTrue(ipv4Default.contains(Address("255.255.255.255")));
- assertTrue(ipv4Default.contains(Address("192.0.2.1")));
- assertFalse(ipv4Default.contains(Address("2001:db8::f00")));
+ assertTrue(ipv4Default.contains(address("255.255.255.255")));
+ assertTrue(ipv4Default.contains(address("192.0.2.1")));
+ assertFalse(ipv4Default.contains(address("2001:db8::f00")));
}
@Test
@@ -315,10 +315,10 @@ public class IpPrefixTest {
p = new IpPrefix(b, random.nextInt(129));
}
if (p.equals(oldP)) {
- assertEquals(p.hashCode(), oldP.hashCode());
+ assertEquals(p.hashCode(), oldP.hashCode());
}
if (p.hashCode() != oldP.hashCode()) {
- assertNotEquals(p, oldP);
+ assertNotEquals(p, oldP);
}
}
}
@@ -332,9 +332,9 @@ public class IpPrefixTest {
new IpPrefix("0.0.0.0/0"),
};
for (int i = 0; i < prefixes.length; i++) {
- for (int j = i + 1; j < prefixes.length; j++) {
- assertNotEquals(prefixes[i].hashCode(), prefixes[j].hashCode());
- }
+ for (int j = i + 1; j < prefixes.length; j++) {
+ assertNotEquals(prefixes[i].hashCode(), prefixes[j].hashCode());
+ }
}
}
@@ -371,8 +371,8 @@ public class IpPrefixTest {
}
public void assertParcelingIsLossless(IpPrefix p) {
- IpPrefix p2 = passThroughParcel(p);
- assertEquals(p, p2);
+ IpPrefix p2 = passThroughParcel(p);
+ assertEquals(p, p2);
}
@Test
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index a24e0d2f93d0..c0802e60103a 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -138,17 +138,29 @@ static bool MergeEntry(IAaptContext* context, const Source& src,
if (src_entry->overlayable_item) {
if (dst_entry->overlayable_item) {
- // Do not allow a resource with an overlayable declaration to have that overlayable
- // declaration redefined
- context->GetDiagnostics()->Error(DiagMessage(src_entry->overlayable_item.value().source)
- << "duplicate overlayable declaration for resource '"
- << src_entry->name << "'");
- context->GetDiagnostics()->Error(DiagMessage(dst_entry->overlayable_item.value().source)
- << "previous declaration here");
- return false;
- } else {
- dst_entry->overlayable_item = std::move(src_entry->overlayable_item);
+ CHECK(src_entry->overlayable_item.value().overlayable != nullptr);
+ Overlayable* src_overlayable = src_entry->overlayable_item.value().overlayable.get();
+
+ CHECK(dst_entry->overlayable_item.value().overlayable != nullptr);
+ Overlayable* dst_overlayable = dst_entry->overlayable_item.value().overlayable.get();
+
+ if (src_overlayable->name != dst_overlayable->name
+ || src_overlayable->actor != dst_overlayable->actor
+ || src_entry->overlayable_item.value().policies !=
+ dst_entry->overlayable_item.value().policies) {
+
+ // Do not allow a resource with an overlayable declaration to have that overlayable
+ // declaration redefined.
+ context->GetDiagnostics()->Error(DiagMessage(src_entry->overlayable_item.value().source)
+ << "duplicate overlayable declaration for resource '"
+ << src_entry->name << "'");
+ context->GetDiagnostics()->Error(DiagMessage(dst_entry->overlayable_item.value().source)
+ << "previous declaration here");
+ return false;
+ }
}
+
+ dst_entry->overlayable_item = std::move(src_entry->overlayable_item);
}
return true;
diff --git a/tools/aapt2/link/TableMerger_test.cpp b/tools/aapt2/link/TableMerger_test.cpp
index ad3674e16774..9dd31e682937 100644
--- a/tools/aapt2/link/TableMerger_test.cpp
+++ b/tools/aapt2/link/TableMerger_test.cpp
@@ -521,6 +521,35 @@ TEST_F(TableMergerTest, SameResourceDifferentNameFail) {
.Build();
auto overlayable_second = std::make_shared<Overlayable>("ThemeResources",
+ "overlay://customization");
+ OverlayableItem overlayable_item_second(overlayable_second);
+ overlayable_item_second.policies |= OverlayableItem::Policy::kProduct;
+ std::unique_ptr<ResourceTable> table_b =
+ test::ResourceTableBuilder()
+ .SetPackageId("com.app.a", 0x7f)
+ .SetOverlayable("bool/foo", overlayable_item_second)
+ .Build();
+
+ ResourceTable final_table;
+ TableMergerOptions options;
+ options.auto_add_overlay = true;
+ TableMerger merger(context_.get(), &final_table, options);
+ ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
+ ASSERT_FALSE(merger.Merge({}, table_b.get(), false /*overlay*/));
+}
+
+TEST_F(TableMergerTest, SameResourceDifferentActorFail) {
+ auto overlayable_first = std::make_shared<Overlayable>("CustomizableResources",
+ "overlay://customization");
+ OverlayableItem overlayable_item_first(overlayable_first);
+ overlayable_item_first.policies |= OverlayableItem::Policy::kProduct;
+ std::unique_ptr<ResourceTable> table_a =
+ test::ResourceTableBuilder()
+ .SetPackageId("com.app.a", 0x7f)
+ .SetOverlayable("bool/foo", overlayable_item_first)
+ .Build();
+
+ auto overlayable_second = std::make_shared<Overlayable>("CustomizableResources",
"overlay://theme");
OverlayableItem overlayable_item_second(overlayable_second);
overlayable_item_second.policies |= OverlayableItem::Policy::kProduct;
@@ -538,7 +567,36 @@ TEST_F(TableMergerTest, SameResourceDifferentNameFail) {
ASSERT_FALSE(merger.Merge({}, table_b.get(), false /*overlay*/));
}
-TEST_F(TableMergerTest, SameResourceSameNameFail) {
+TEST_F(TableMergerTest, SameResourceDifferentPoliciesFail) {
+ auto overlayable_first = std::make_shared<Overlayable>("CustomizableResources",
+ "overlay://customization");
+ OverlayableItem overlayable_item_first(overlayable_first);
+ overlayable_item_first.policies |= OverlayableItem::Policy::kProduct;
+ std::unique_ptr<ResourceTable> table_a =
+ test::ResourceTableBuilder()
+ .SetPackageId("com.app.a", 0x7f)
+ .SetOverlayable("bool/foo", overlayable_item_first)
+ .Build();
+
+ auto overlayable_second = std::make_shared<Overlayable>("CustomizableResources",
+ "overlay://customization");
+ OverlayableItem overlayable_item_second(overlayable_second);
+ overlayable_item_second.policies |= OverlayableItem::Policy::kSignature;
+ std::unique_ptr<ResourceTable> table_b =
+ test::ResourceTableBuilder()
+ .SetPackageId("com.app.a", 0x7f)
+ .SetOverlayable("bool/foo", overlayable_item_second)
+ .Build();
+
+ ResourceTable final_table;
+ TableMergerOptions options;
+ options.auto_add_overlay = true;
+ TableMerger merger(context_.get(), &final_table, options);
+ ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
+ ASSERT_FALSE(merger.Merge({}, table_b.get(), false /*overlay*/));
+}
+
+TEST_F(TableMergerTest, SameResourceSameOverlayable) {
auto overlayable = std::make_shared<Overlayable>("CustomizableResources",
"overlay://customization");
@@ -551,7 +609,7 @@ TEST_F(TableMergerTest, SameResourceSameNameFail) {
.Build();
OverlayableItem overlayable_item_second(overlayable);
- overlayable_item_second.policies |= OverlayableItem::Policy::kSystem;
+ overlayable_item_second.policies |= OverlayableItem::Policy::kProduct;
std::unique_ptr<ResourceTable> table_b =
test::ResourceTableBuilder()
.SetPackageId("com.app.a", 0x7f)
@@ -563,7 +621,7 @@ TEST_F(TableMergerTest, SameResourceSameNameFail) {
options.auto_add_overlay = true;
TableMerger merger(context_.get(), &final_table, options);
ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
- ASSERT_FALSE(merger.Merge({}, table_b.get(), false /*overlay*/));
+ ASSERT_TRUE(merger.Merge({}, table_b.get(), false /*overlay*/));
}
} // namespace aapt