diff options
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 |