diff --git a/Android.mk b/Android.mk index 3b78e51a93a3..959d8e3f1d74 100644 --- a/Android.mk +++ b/Android.mk @@ -179,6 +179,7 @@ LOCAL_SRC_FILES += \ core/java/android/content/pm/IPinItemRequest.aidl \ core/java/android/content/pm/IShortcutService.aidl \ core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl \ + core/java/android/content/substratum/ISubstratumService.aidl \ core/java/android/database/IContentObserver.aidl \ ../av/camera/aidl/android/hardware/ICameraService.aidl \ ../av/camera/aidl/android/hardware/ICameraServiceListener.aidl \ @@ -408,6 +409,7 @@ LOCAL_SRC_FILES += \ core/java/com/android/internal/os/IShellCallback.aidl \ core/java/com/android/internal/statusbar/IStatusBar.aidl \ core/java/com/android/internal/statusbar/IStatusBarService.aidl \ + core/java/com/android/internal/substratum/ISubstratumHelperService.aidl \ core/java/com/android/internal/textservice/ISpellCheckerService.aidl \ core/java/com/android/internal/textservice/ISpellCheckerServiceCallback.aidl \ core/java/com/android/internal/textservice/ISpellCheckerSession.aidl \ diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index fc8baaeb4e85..f4ecf08b8ca9 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -72,8 +72,10 @@ namespace android { static const char OEM_BOOTANIMATION_FILE[] = "/oem/media/bootanimation.zip"; static const char SYSTEM_BOOTANIMATION_FILE[] = "/system/media/bootanimation.zip"; static const char SYSTEM_ENCRYPTED_BOOTANIMATION_FILE[] = "/system/media/bootanimation-encrypted.zip"; +static const char THEME_BOOTANIMATION_FILE[] = "/data/system/theme/bootanimation.zip"; static const char OEM_SHUTDOWNANIMATION_FILE[] = "/oem/media/shutdownanimation.zip"; static const char SYSTEM_SHUTDOWNANIMATION_FILE[] = "/system/media/shutdownanimation.zip"; +static const char THEME_SHUTDOWNANIMATION_FILE[] = "/data/system/theme/shutdownanimation.zip"; static const char SYSTEM_DATA_DIR_PATH[] = "/data/system"; static const char SYSTEM_TIME_DIR_NAME[] = "time"; @@ -347,9 +349,10 @@ status_t BootAnimation::readyToRun() { mZipFileName = getAnimationFileName(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE,mShuttingDown); return NO_ERROR; } - static const char* bootFiles[] = {OEM_BOOTANIMATION_FILE, SYSTEM_BOOTANIMATION_FILE}; + static const char* bootFiles[] = + {THEME_BOOTANIMATION_FILE, OEM_BOOTANIMATION_FILE, SYSTEM_BOOTANIMATION_FILE}; static const char* shutdownFiles[] = - {OEM_SHUTDOWNANIMATION_FILE, SYSTEM_SHUTDOWNANIMATION_FILE}; + {THEME_SHUTDOWNANIMATION_FILE, OEM_SHUTDOWNANIMATION_FILE, SYSTEM_SHUTDOWNANIMATION_FILE}; for (const char* f : (!mShuttingDown ? bootFiles : shutdownFiles)) { if (access(getAnimationFileName(f,mShuttingDown), R_OK) == 0) { diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index ea9369181f65..3acac65b065b 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -51,6 +51,7 @@ import android.database.sqlite.SQLiteDebug.DbStats; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Typeface; import android.hardware.display.DisplayManagerGlobal; import android.net.ConnectivityManager; import android.net.IConnectivityManager; @@ -5093,11 +5094,15 @@ static void freeTextLayoutCachesIfNeeded(int configDiff) { if (configDiff != 0) { // Ask text layout engine to free its caches if there is a locale change boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); - if (hasLocaleConfigChange) { - Canvas.freeTextLayoutCaches(); - if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); - } - } + boolean hasFontConfigChange = ((configDiff & ActivityInfo.CONFIG_THEME_FONT) != 0); + if (hasLocaleConfigChange || hasFontConfigChange) { + Canvas.freeTextLayoutCaches(); + if (hasFontConfigChange) { + Typeface.recreateDefaults(); + } + if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); + } + } } /** diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 7caeca3da6f8..4e573ba70431 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -2741,7 +2741,11 @@ public static class Builder { */ private static final int LIGHTNESS_TEXT_DIFFERENCE_DARK = -10; + private static final String MEDIA_ARTWORK_COLORIZED_EXTRAS = + "notification.mediaArtworkColorized"; + private Context mContext; + private Context mThemeContext; private Notification mN; private Bundle mUserExtras = new Bundle(); private Style mStyle; @@ -2783,6 +2787,7 @@ public static class Builder { private boolean mTintActionButtons; private boolean mInNightMode; + private boolean mAllowIconTextTint; /** * Constructs a new Builder with the defaults: @@ -2814,9 +2819,18 @@ public Builder(Context context) { * @hide */ public Builder(Context context, Notification toAdopt) { + this(context, toAdopt, context); + } + + /** + * @hide + */ + public Builder(Context context, Notification toAdopt, Context themeContext) { mContext = context; - Resources res = mContext.getResources(); + mThemeContext = themeContext; + Resources res = mThemeContext.getResources(); mTintActionButtons = res.getBoolean(R.bool.config_tintNotificationActionButtons); + mAllowIconTextTint = res.getBoolean(R.bool.config_allowNotificationIconTextTinting); if (res.getBoolean(R.bool.config_enableNightMode)) { Configuration currentConfig = res.getConfiguration(); @@ -2877,11 +2891,25 @@ public Builder(Context context, Notification toAdopt) { private NotificationColorUtil getColorUtil() { if (mColorUtil == null) { - mColorUtil = NotificationColorUtil.getInstance(mContext); + mColorUtil = NotificationColorUtil.getInstance(mThemeContext); } return mColorUtil; } + /** + * @hide + */ + public void setArtworkColorizedExtras(boolean value) { + mN.extras.putBoolean(MEDIA_ARTWORK_COLORIZED_EXTRAS, true); + } + + /** + * @hide + */ + public boolean getArtworkColorizedExtras() { + return mN.extras.getBoolean(MEDIA_ARTWORK_COLORIZED_EXTRAS, false); + } + /** * If this notification is duplicative of a Launcher shortcut, sets the * {@link ShortcutInfo#getId() id} of the shortcut, in case the Launcher wants to hide @@ -3816,7 +3844,7 @@ private Bitmap getProfileBadge() { if (badge == null) { return null; } - final int size = mContext.getResources().getDimensionPixelSize( + final int size = mThemeContext.getResources().getDimensionPixelSize( R.dimen.notification_badge_size); Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); @@ -3886,7 +3914,7 @@ private RemoteViews applyStandardTemplate(int resId, boolean hasProgress) { } private RemoteViews applyStandardTemplate(int resId, StandardTemplateParams p) { - RemoteViews contentView = new BuilderRemoteViews(mContext.getApplicationInfo(), resId); + RemoteViews contentView = new BuilderRemoteViews(mThemeContext.getApplicationInfo(), resId); resetStandardTemplate(contentView); @@ -3979,9 +4007,9 @@ private void ensureColors() { || mTextColorsAreForBackground != backgroundColor) { mTextColorsAreForBackground = backgroundColor; if (!hasForegroundColor() || !isColorized()) { - mPrimaryTextColor = NotificationColorUtil.resolvePrimaryColor(mContext, + mPrimaryTextColor = NotificationColorUtil.resolvePrimaryColor(mThemeContext, backgroundColor); - mSecondaryTextColor = NotificationColorUtil.resolveSecondaryColor(mContext, + mSecondaryTextColor = NotificationColorUtil.resolveSecondaryColor(mThemeContext, backgroundColor); if (backgroundColor != COLOR_DEFAULT && (mBackgroundColorHint != COLOR_INVALID || isColorized())) { @@ -4049,7 +4077,7 @@ && satisfiesTextContrast(backgroundColor, Color.BLACK) } } } - mActionBarColor = NotificationColorUtil.resolveActionBarColor(mContext, + mActionBarColor = NotificationColorUtil.resolveActionBarColor(mThemeContext, backgroundColor); } } @@ -4074,7 +4102,7 @@ void setContentMinHeight(RemoteViews remoteView, boolean hasMinHeight) { int minHeight = 0; if (hasMinHeight) { // we need to set the minHeight of the notification - minHeight = mContext.getResources().getDimensionPixelSize( + minHeight = mThemeContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.notification_min_content_height); } remoteView.setInt(R.id.notification_main_column, "setMinimumHeight", minHeight); @@ -4089,7 +4117,7 @@ private boolean handleProgressBar(boolean hasProgress, RemoteViews contentView, contentView.setProgressBar( R.id.progress, max, progress, ind); contentView.setProgressBackgroundTintList( - R.id.progress, ColorStateList.valueOf(mContext.getColor( + R.id.progress, ColorStateList.valueOf(mThemeContext.getColor( R.color.notification_progress_background_color))); if (mN.color != COLOR_DEFAULT) { ColorStateList colorStateList = ColorStateList.valueOf(resolveContrastColor()); @@ -4339,7 +4367,7 @@ private RemoteViews applyStandardTemplateWithActions(int layoutId, } else if (isColorized()) { big.setInt(R.id.actions, "setBackgroundColor", getActionBarColor()); } else { - big.setInt(R.id.actions, "setBackgroundColor", mContext.getColor( + big.setInt(R.id.actions, "setBackgroundColor", mThemeContext.getColor( R.color.notification_action_list)); } big.setViewLayoutMarginBottomDimen(R.id.notification_action_list_margin_target, @@ -4468,7 +4496,7 @@ public RemoteViews createBigContentView() { public RemoteViews makeNotificationHeader(boolean ambient) { Boolean colorized = (Boolean) mN.extras.get(EXTRA_COLORIZED); mN.extras.putBoolean(EXTRA_COLORIZED, false); - RemoteViews header = new BuilderRemoteViews(mContext.getApplicationInfo(), + RemoteViews header = new BuilderRemoteViews(mThemeContext.getApplicationInfo(), ambient ? R.layout.notification_template_ambient_header : R.layout.notification_template_header); resetNotificationHeader(header); @@ -4585,7 +4613,7 @@ private RemoteViews makePublicView(boolean ambient) { RemoteViews view; if (ambient) { publicExtras.putCharSequence(EXTRA_TITLE, - mContext.getString(com.android.internal.R.string.notification_hidden_text)); + mThemeContext.getString(com.android.internal.R.string.notification_hidden_text)); view = makeAmbientNotification(); } else{ view = makeNotificationHeader(false /* ambient */); @@ -4644,7 +4672,7 @@ private CharSequence createSummaryText() { } CharSequence contentText = mN.extras.getCharSequence(Notification.EXTRA_TEXT); if (titleText != null && contentText != null) { - summary.append(bidi.unicodeWrap(mContext.getText( + summary.append(bidi.unicodeWrap(mThemeContext.getText( R.string.notification_header_divider_symbol_with_spaces))); } if (contentText != null) { @@ -4656,7 +4684,7 @@ private CharSequence createSummaryText() { private RemoteViews generateActionButton(Action action, boolean emphazisedMode, boolean oddAction, boolean ambient) { final boolean tombstone = (action.actionIntent == null); - RemoteViews button = new BuilderRemoteViews(mContext.getApplicationInfo(), + RemoteViews button = new BuilderRemoteViews(mThemeContext.getApplicationInfo(), emphazisedMode ? getEmphasizedActionLayoutResource() : tombstone ? getActionTombstoneLayoutResource() : getActionLayoutResource()); @@ -4674,7 +4702,7 @@ private RemoteViews generateActionButton(Action action, boolean emphazisedMode, if (isColorized()) { bgColor = oddAction ? getActionBarColor() : getActionBarColorDeEmphasized(); } else { - bgColor = mContext.getColor(oddAction ? R.color.notification_action_list + bgColor = mThemeContext.getColor(oddAction ? R.color.notification_action_list : R.color.notification_action_list_dark); } button.setDrawableParameters(R.id.button_holder, true, -1, bgColor, @@ -4809,7 +4837,12 @@ private CharSequence processLegacyText(CharSequence charSequence, boolean ambien private void processSmallIconColor(Icon smallIcon, RemoteViews contentView, boolean ambient) { boolean colorable = !isLegacy() || getColorUtil().isGrayscaleIcon(mContext, smallIcon); - int color = ambient ? resolveAmbientColor() : getPrimaryHighlightColor(); + int color; + if (!mAllowIconTextTint) { + color = ambient ? resolveAmbientColor() : mThemeContext.getColor(R.color.notification_icon_default_color); + } else { + color = ambient ? resolveAmbientColor() : getPrimaryHighlightColor(); + } if (colorable) { contentView.setDrawableParameters(R.id.icon, false, -1, color, PorterDuff.Mode.SRC_ATOP, -1); @@ -4828,7 +4861,7 @@ private void processLargeLegacyIcon(Icon largeIcon, RemoteViews contentView) { if (largeIcon != null && isLegacy() && getColorUtil().isGrayscaleIcon(mContext, largeIcon)) { // resolve color will fall back to the default when legacy - contentView.setDrawableParameters(R.id.icon, false, -1, resolveContrastColor(), + contentView.setDrawableParameters(R.id.icon, false, -1, resolveIconContrastColor(), PorterDuff.Mode.SRC_ATOP, -1); } } @@ -4839,7 +4872,23 @@ private void sanitizeColor() { } } + int getSenderTextColor() { + return mThemeContext.getColor(R.color.sender_text_color); + } + + int resolveIconContrastColor() { + if (!mAllowIconTextTint) { + return mThemeContext.getColor(R.color.notification_icon_default_color); + } else { + return resolveContrastColor(); + } + } + int resolveContrastColor() { + if (!mAllowIconTextTint) { + return mThemeContext.getColor(R.color.notification_text_default_color); + } + if (mCachedContrastColorIsFor == mN.color && mCachedContrastColor != COLOR_INVALID) { return mCachedContrastColor; } @@ -4847,15 +4896,17 @@ int resolveContrastColor() { int color; int background = mBackgroundColorHint; if (mBackgroundColorHint == COLOR_INVALID) { - background = mContext.getColor( + background = mThemeContext.getColor( com.android.internal.R.color.notification_material_background_color); } if (mN.color == COLOR_DEFAULT) { ensureColors(); color = mSecondaryTextColor; } else { - color = NotificationColorUtil.resolveContrastColor(mContext, mN.color, - background, mInNightMode); + boolean isDark = mInNightMode || mThemeContext.getResources() + .getBoolean(R.bool.config_useDarkBgNotificationIconTextTinting); + color = NotificationColorUtil.resolveContrastColor(mThemeContext, mN.color, + background, isDark); } if (Color.alpha(color) < 255) { // alpha doesn't go well for color filters, so let's blend it manually @@ -4869,7 +4920,7 @@ int resolveAmbientColor() { if (mCachedAmbientColorIsFor == mN.color && mCachedAmbientColorIsFor != COLOR_INVALID) { return mCachedAmbientColor; } - final int contrasted = NotificationColorUtil.resolveAmbientColor(mContext, mN.color); + final int contrasted = NotificationColorUtil.resolveAmbientColor(mThemeContext, mN.color); mCachedAmbientColorIsFor = mN.color; return mCachedAmbientColor = contrasted; @@ -4917,7 +4968,7 @@ public static Notification.Builder recoverBuilder(Context context, Notification builderContext = context; // try with given context } - return new Builder(builderContext, n); + return new Builder(builderContext, n, context); } /** @@ -6026,7 +6077,7 @@ private void fixTitleAndTextExtras(Bundle extras) { if (!TextUtils.isEmpty(mConversationTitle)) { if (!TextUtils.isEmpty(sender)) { BidiFormatter bidi = BidiFormatter.getInstance(); - title = mBuilder.mContext.getString( + title = mBuilder.mThemeContext.getString( com.android.internal.R.string.notification_messaging_title_template, bidi.unicodeWrap(mConversationTitle), bidi.unicodeWrap(m.mSender)); } else { @@ -6217,7 +6268,7 @@ private CharSequence makeMessageLine(Message m, Builder builder) { sb.append(bidi.unicodeWrap(m.mSender), makeFontColorSpan(colorize ? builder.getPrimaryTextColor() - : Color.BLACK), + : builder.getSenderTextColor()), 0 /* flags */); } CharSequence text = m.mText == null ? "" : m.mText; @@ -6531,7 +6582,7 @@ public RemoteViews makeBigContentView() { } int i=0; - int topPadding = mBuilder.mContext.getResources().getDimensionPixelSize( + int topPadding = mBuilder.mThemeContext.getResources().getDimensionPixelSize( R.dimen.notification_inbox_item_top_padding); boolean first = true; int onlyViewId = 0; @@ -6559,7 +6610,7 @@ public RemoteViews makeBigContentView() { } if (onlyViewId != 0) { // We only have 1 entry, lets make it look like the normal Text of a Bigtext - topPadding = mBuilder.mContext.getResources().getDimensionPixelSize( + topPadding = mBuilder.mThemeContext.getResources().getDimensionPixelSize( R.dimen.notification_text_margin_top); contentView.setViewPadding(onlyViewId, 0, topPadding, 0, 0); } @@ -6740,7 +6791,7 @@ private RemoteViews generateMediaActionButton(Action action, int color) { // notification color. Otherwise, just use the passed-in color. int tintColor = mBuilder.shouldTintActionButtons() || mBuilder.isColorized() ? color - : NotificationColorUtil.resolveColor(mBuilder.mContext, + : NotificationColorUtil.resolveColor(mBuilder.mThemeContext, Notification.COLOR_DEFAULT); button.setDrawableParameters(R.id.action0, false, -1, tintColor, diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index e0c3f75e223e..cbd421ac3c67 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -756,6 +756,11 @@ public class ActivityInfo extends ComponentInfo * {@link android.R.attr#configChanges} attribute. */ public static final int CONFIG_LAYOUT_DIRECTION = 0x2000; + /** + * Bit in {@link #configChanges} that indicates a font change occurred + * @hide + */ + public static final int CONFIG_THEME_FONT = 0x200000; /** * Bit in {@link #configChanges} that indicates that the activity * can itself handle the change to the display color gamut or dynamic diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java index ba488f6a0518..3230ee715571 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -286,8 +286,26 @@ public class PackageInfo implements Parcelable { /** @hide */ public int overlayPriority; - /** @hide */ - public boolean isStaticOverlay; + + /** + * Flag for use with {@link #overlayFlags}. Marks the overlay as static, meaning it cannot + * be enabled/disabled at runtime. + * @hide + */ + public static final int FLAG_OVERLAY_STATIC = 1 << 1; + + /** + * Flag for use with {@link #overlayFlags}. Marks the overlay as trusted (not 3rd party). + * @hide + */ + public static final int FLAG_OVERLAY_TRUSTED = 1 << 2; + + /** + * Modifiers that affect the state of this overlay. See {@link #FLAG_OVERLAY_STATIC}, + * {@link #FLAG_OVERLAY_TRUSTED}. + * @hide + */ + public int overlayFlags; public PackageInfo() { } @@ -342,8 +360,8 @@ public void writeToParcel(Parcel dest, int parcelableFlags) { dest.writeString(restrictedAccountType); dest.writeString(requiredAccountType); dest.writeString(overlayTarget); - dest.writeInt(isStaticOverlay ? 1 : 0); dest.writeInt(overlayPriority); + dest.writeInt(overlayFlags); } public static final Parcelable.Creator CREATOR @@ -394,8 +412,8 @@ private PackageInfo(Parcel source) { restrictedAccountType = source.readString(); requiredAccountType = source.readString(); overlayTarget = source.readString(); - isStaticOverlay = source.readInt() != 0; overlayPriority = source.readInt(); + overlayFlags = source.readInt(); // The component lists were flattened with the redundant ApplicationInfo // instances omitted. Distribute the canonical one here as appropriate. diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 3bd4d105f759..60102fe87a9d 100755 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -693,7 +693,15 @@ public static PackageInfo generatePackageInfo(PackageParser.Package p, pi.requiredAccountType = p.mRequiredAccountType; pi.overlayTarget = p.mOverlayTarget; pi.overlayPriority = p.mOverlayPriority; - pi.isStaticOverlay = p.mIsStaticOverlay; + + if (p.mIsStaticOverlay) { + pi.overlayFlags |= PackageInfo.FLAG_OVERLAY_STATIC; + } + + if (p.mTrustedOverlay) { + pi.overlayFlags |= PackageInfo.FLAG_OVERLAY_TRUSTED; + } + pi.firstInstallTime = firstInstallTime; pi.lastUpdateTime = lastUpdateTime; if ((flags&PackageManager.GET_GIDS) != 0) { diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index f7cccd56f079..5995bda302c6 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -1112,6 +1112,7 @@ public void unset() { int changed = 0; if (delta.fontScale > 0 && fontScale != delta.fontScale) { changed |= ActivityInfo.CONFIG_FONT_SCALE; + changed |= ActivityInfo.CONFIG_THEME_FONT; fontScale = delta.fontScale; } if (delta.mcc != 0 && mcc != delta.mcc) { @@ -1277,6 +1278,7 @@ public void unset() { } if (delta.assetsSeq != ASSETS_SEQ_UNDEFINED && delta.assetsSeq != assetsSeq) { changed |= ActivityInfo.CONFIG_ASSETS_PATHS; + changed |= ActivityInfo.CONFIG_THEME_FONT; assetsSeq = delta.assetsSeq; } if (delta.seq != 0) { @@ -1342,6 +1344,7 @@ public int diff(Configuration delta, boolean compareUndefined, boolean publicOnl int changed = 0; if ((compareUndefined || delta.fontScale > 0) && fontScale != delta.fontScale) { changed |= ActivityInfo.CONFIG_FONT_SCALE; + changed |= ActivityInfo.CONFIG_THEME_FONT; } if ((compareUndefined || delta.mcc != 0) && mcc != delta.mcc) { changed |= ActivityInfo.CONFIG_MCC; @@ -1431,6 +1434,7 @@ && getScreenLayoutNoDirection(screenLayout) != if ((compareUndefined || delta.assetsSeq != ASSETS_SEQ_UNDEFINED) && assetsSeq != delta.assetsSeq) { changed |= ActivityInfo.CONFIG_ASSETS_PATHS; + changed |= ActivityInfo.CONFIG_THEME_FONT; } // Make sure that one of the values is not null and that they are not equal. @@ -1462,7 +1466,7 @@ public static boolean needNewResources(@Config int configChanges, // CONFIG_ASSETS_PATHS and CONFIG_FONT_SCALE are higher level configuration changes that // all resources are subject to change with. interestingChanges = interestingChanges | ActivityInfo.CONFIG_ASSETS_PATHS - | ActivityInfo.CONFIG_FONT_SCALE; + | ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_THEME_FONT; return (configChanges & interestingChanges) != 0; } diff --git a/core/java/android/content/substratum/ISubstratumService.aidl b/core/java/android/content/substratum/ISubstratumService.aidl new file mode 100644 index 000000000000..da71ba326db8 --- /dev/null +++ b/core/java/android/content/substratum/ISubstratumService.aidl @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2018 Projekt Substratum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.substratum; + +interface ISubstratumService { + + /** + * Install a list of specified overlay packages + * + * @param paths Filled in with a list of path names for packages to be installed from. + */ + void installOverlay(in List paths); + + /** + * Uninstall a list of specified overlay packages + * + * @param packages Filled in with a list of path names for packages to be installed from. + * @param restartUi Flag to automatically restart the SystemUI. + */ + void uninstallOverlay(in List packages, boolean restartUi); + + /** + * Switch the state of specified overlay packages + * + * @param packages Filled in with a list of package names to be switched. + * @param enable Whether to enable the specified overlays. + * @param restartUi Flag to automatically restart the SystemUI. + */ + void switchOverlay(in List packages, boolean enable, boolean restartUi); + + /** + * Change the priority of a specified list of overlays + * + * @param packages Filled in with a list of package names to be reordered. + * @param restartUi Flag to automatically restart the SystemUI. + */ + void setPriority(in List packages, boolean restartUi); + + /** + * Restart SystemUI + */ + void restartSystemUI(); + + /** + * Copy Method + * + * @param source Path of the source file. + * @param destination Path of the source file to be copied to. + */ + void copy(String source, String destination); + + /** + * Move Method + * + * @param source Path of the source file. + * @param destination Path of the source file to be moved to. + */ + void move(String source, String destination); + + /** + * Create Directory Method + * + * @param destination Path of the created destination folder. + */ + void mkdir(String destination); + + /** + * Delete Directory Method + * + * @param destination Path of the directory to be deleted. + * @param withParent Flag to automatically delete the folder encompassing the folder. + */ + void deleteDirectory(String directory, boolean withParent); + + /** + * Apply a specified bootanimation + * + * @param name Path to extract the bootanimation archive from. + */ + void applyBootanimation(String name); + + /** + * Apply a specified font pack + * + * @param name Path to extract the font archive from. + */ + void applyFonts(String pid, String fileName); + + /** + * Apply a specified sound pack + * + * @param name Path to extract the sounds archive from. + */ + void applySounds(String pid, String fileName); + + /** + * Profile Applicator + * + * @param enable Filled in with a list of package names to be enabled. + * @param disable Filled in with a list of package names to be disabled. + * @param name Name of the profile to be applied. + * @param restartUi Flag to automatically restart the SystemUI. + */ + void applyProfile(in List enable, in List disable, String name, + boolean restartUi); + + /** + * Apply a specified shutdownanimation + * + * @param name Path to extract the shutdown archive from. + * Use null to clear applied custom shutdown + */ + void applyShutdownAnimation(String name); + + /** + * Returns information about all installed overlay packages for the + * specified user. If there are no installed overlay packages for this user, + * an empty map is returned (i.e. null is never returned). The returned map is a + * mapping of target package names to lists of overlays. Each list for a + * given target package is sorted in priority order, with the overlay with + * the highest priority at the end of the list. + * + * @param uid The user to get the OverlayInfos for. + * @return A Map> with target package names + * mapped to lists of overlays; if no overlays exist for the + * requested user, an empty map is returned. + */ + Map getAllOverlays(in int uid); +} + diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java index 9edcc0e9b8d4..b7d1df3068b4 100644 --- a/core/java/android/net/Uri.java +++ b/core/java/android/net/Uri.java @@ -2344,7 +2344,8 @@ public Uri getCanonicalUri() { */ public void checkFileUriExposed(String location) { if ("file".equals(getScheme()) - && (getPath() != null) && !getPath().startsWith("/system/")) { + && (getPath() != null) && !(getPath().startsWith("/system/") || + getPath().startsWith("/data/system/theme/"))) { StrictMode.onFileUriExposed(this, location); } } diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 9e87ee7eaef5..dc66d90be674 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -458,10 +458,11 @@ public static final ProcessStartResult start(final String processClass, String instructionSet, String appDataDir, String invokeWith, - String[] zygoteArgs) { + String[] zygoteArgs, + boolean refreshFont) { return zygoteProcess.start(processClass, niceName, uid, gid, gids, debugFlags, mountExternal, targetSdkVersion, seInfo, - abi, instructionSet, appDataDir, invokeWith, zygoteArgs); + abi, instructionSet, appDataDir, invokeWith, zygoteArgs, refreshFont); } /** @hide */ @@ -475,10 +476,11 @@ public static final ProcessStartResult startWebView(final String processClass, String instructionSet, String appDataDir, String invokeWith, - String[] zygoteArgs) { + String[] zygoteArgs, + boolean refreshFont) { return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids, debugFlags, mountExternal, targetSdkVersion, seInfo, - abi, instructionSet, appDataDir, invokeWith, zygoteArgs); + abi, instructionSet, appDataDir, invokeWith, zygoteArgs, refreshFont); } /** diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index 7a13ee89d393..11f9918a6b4c 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -203,11 +203,12 @@ public final Process.ProcessStartResult start(final String processClass, String instructionSet, String appDataDir, String invokeWith, - String[] zygoteArgs) { + String[] zygoteArgs, + boolean refreshFont) { try { return startViaZygote(processClass, niceName, uid, gid, gids, debugFlags, mountExternal, targetSdkVersion, seInfo, - abi, instructionSet, appDataDir, invokeWith, zygoteArgs); + abi, instructionSet, appDataDir, invokeWith, zygoteArgs, refreshFont); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); @@ -338,7 +339,8 @@ private Process.ProcessStartResult startViaZygote(final String processClass, String instructionSet, String appDataDir, String invokeWith, - String[] extraArgs) + String[] extraArgs, + boolean refreshFont) throws ZygoteStartFailedEx { ArrayList argsForZygote = new ArrayList(); @@ -382,6 +384,9 @@ private Process.ProcessStartResult startViaZygote(final String processClass, argsForZygote.add("--mount-external-write"); } argsForZygote.add("--target-sdk-version=" + targetSdkVersion); + if (refreshFont) { + argsForZygote.add("--refresh-font"); + } // --setgroups is a comma-separated list if (gids != null && gids.length > 0) { diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index fd8989c549cf..1d027579befc 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7299,6 +7299,13 @@ public static boolean putFloatForUser(ContentResolver cr, String name, float val */ public static final String QS_AUTO_ADDED_TILES = "qs_auto_tiles"; + /** + * Force authorize Substratum (or equivalent) frontend calling packages by ThemeInterfacer + * The value is boolean (1 or 0). + * @hide + */ + public static final String FORCE_AUTHORIZE_SUBSTRATUM_PACKAGES = "force_authorize_substratum_packages"; + /** * This are the settings to be backed up. * diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java index ed583907123b..ca4337e81ca8 100644 --- a/core/java/android/text/FontConfig.java +++ b/core/java/android/text/FontConfig.java @@ -25,6 +25,7 @@ import android.net.Uri; import java.lang.annotation.Retention; +import java.util.List; /** @@ -32,10 +33,10 @@ * @hide */ public final class FontConfig { - private final @NonNull Family[] mFamilies; - private final @NonNull Alias[] mAliases; + private final @NonNull List mFamilies; + private final @NonNull List mAliases; - public FontConfig(@NonNull Family[] families, @NonNull Alias[] aliases) { + public FontConfig(@NonNull List families, @NonNull List aliases) { mFamilies = families; mAliases = aliases; } @@ -43,14 +44,14 @@ public FontConfig(@NonNull Family[] families, @NonNull Alias[] aliases) { /** * Returns the ordered list of families included in the system fonts. */ - public @NonNull Family[] getFamilies() { + public @NonNull List getFamilies() { return mFamilies; } /** * Returns the list of aliases defined for the font families in the system fonts. */ - public @NonNull Alias[] getAliases() { + public @NonNull List getAliases() { return mAliases; } @@ -167,7 +168,7 @@ public int getWeight() { * Class that holds information about a Font family. */ public static final class Family { - private final @NonNull String mName; + private String mName; private final @NonNull Font[] mFonts; private final @NonNull String mLanguage; @@ -211,6 +212,10 @@ public Family(@NonNull String name, @NonNull Font[] fonts, @NonNull String langu mVariant = variant; } + public void clearName() { + mName = null; + } + /** * Returns the name given by the system to this font family. */ diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index 9fa3239b60cf..52a4877046c1 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -26,6 +26,7 @@ import static com.android.internal.os.ZygoteConnectionConstants.MAX_ZYGOTE_ARGC; import static com.android.internal.os.ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS; +import android.graphics.Typeface; import android.net.Credentials; import android.net.LocalSocket; import android.os.FactoryTest; @@ -191,6 +192,10 @@ Runnable processOneCommand(ZygoteServer zygoteServer) { } } + if (parsedArgs.refreshFont) { + Typeface.recreateDefaults(); + } + /** * In order to avoid leaking descriptors to the Zygote child, * the native code must close the two Zygote socket descriptors @@ -416,6 +421,11 @@ static class Arguments { */ boolean preloadDefault; + /** + * Whether to refresh displayed font + */ + boolean refreshFont; + /** * Constructs instance and parses args * @param args zygote command-line args @@ -582,6 +592,8 @@ private void parseArgs(String args[]) preloadPackageCacheKey = args[++curArg]; } else if (arg.equals("--preload-default")) { preloadDefault = true; + } else if (arg.equals("--refresh-font")) { + refreshFont = true; } else { break; } diff --git a/core/java/com/android/internal/substratum/ISubstratumHelperService.aidl b/core/java/com/android/internal/substratum/ISubstratumHelperService.aidl new file mode 100644 index 000000000000..7d6ac0aa1762 --- /dev/null +++ b/core/java/com/android/internal/substratum/ISubstratumHelperService.aidl @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2018 Projekt Substratum + * + * 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.internal.substratum; + +oneway interface ISubstratumHelperService { + void applyBootAnimation(); + void applyShutdownAnimation(); + void applyProfile(in String name); +} diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java index 933cc7af975a..491b9a8d5a54 100644 --- a/core/java/com/android/internal/util/NotificationColorUtil.java +++ b/core/java/com/android/internal/util/NotificationColorUtil.java @@ -40,6 +40,8 @@ import android.util.Log; import android.util.Pair; +import com.android.internal.R; + import java.util.Arrays; import java.util.WeakHashMap; @@ -457,8 +459,10 @@ public static int resolveColor(Context context, int color) { */ public static int resolveContrastColor(Context context, int notificationColor, int backgroundColor) { + boolean isDark = context.getResources() + .getBoolean(R.bool.config_useDarkBgNotificationIconTextTinting); return NotificationColorUtil.resolveContrastColor(context, notificationColor, - backgroundColor, false /* isDark */); + backgroundColor, isDark); } /** @@ -515,7 +519,12 @@ public static int resolveAmbientColor(Context context, int notificationColor) { final int resolvedColor = resolveColor(context, notificationColor); int color = resolvedColor; - color = NotificationColorUtil.ensureTextContrastOnBlack(color); + + if (!context.getResources().getBoolean(R.bool.config_allowNotificationIconTextTinting)) { + color = context.getColor(R.color.notification_ambient_default_color); + } else { + color = NotificationColorUtil.ensureTextContrastOnBlack(color); + } if (color != resolvedColor) { if (DEBUG){ diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index a711a1bbeea5..f1e71f80fc0e 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -580,6 +580,10 @@ + + + + diff --git a/core/res/res/drawable/toast_frame.xml b/core/res/res/drawable/toast_frame.xml index d57bd6a554e1..085e081c80db 100644 --- a/core/res/res/drawable/toast_frame.xml +++ b/core/res/res/drawable/toast_frame.xml @@ -18,7 +18,6 @@ - + - diff --git a/core/res/res/layout/app_permission_item.xml b/core/res/res/layout/app_permission_item.xml index 383d771074e0..a80d40efd2be 100644 --- a/core/res/res/layout/app_permission_item.xml +++ b/core/res/res/layout/app_permission_item.xml @@ -32,7 +32,7 @@ android:layout_marginStart="16dp" android:layout_marginEnd="8dp" android:scaleType="fitCenter" - android:tint="@android:color/black"/> + android:tint="@color/app_permission_icon_tint"/> + android:background="@color/resolver_list_bg" > @@ -47,7 +47,7 @@ android:paddingTop="8dp" android:scaleType="center" android:src="@drawable/ic_expand_more_48dp" - android:tint="?android:attr/colorAccent"/> + android:tint="@color/immersive_cling_bg_color"/>