diff options
46 files changed, 784 insertions, 552 deletions
diff --git a/api/current.txt b/api/current.txt index 2bc97642bc24..77cb9e490b04 100644 --- a/api/current.txt +++ b/api/current.txt @@ -40890,11 +40890,10 @@ package android.text { } public final class FontConfig implements android.os.Parcelable { - ctor public FontConfig(); - ctor public FontConfig(android.text.FontConfig); + ctor public FontConfig(android.text.FontConfig.Family[], android.text.FontConfig.Alias[]); method public int describeContents(); - method public java.util.List<android.text.FontConfig.Alias> getAliases(); - method public java.util.List<android.text.FontConfig.Family> getFamilies(); + method public android.text.FontConfig.Alias[] getAliases(); + method public android.text.FontConfig.Family[] getFamilies(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.text.FontConfig> CREATOR; } @@ -40919,22 +40918,22 @@ package android.text { } public static final class FontConfig.Family implements android.os.Parcelable { - ctor public FontConfig.Family(java.lang.String, java.util.List<android.text.FontConfig.Font>, java.lang.String, java.lang.String); - ctor public FontConfig.Family(android.text.FontConfig.Family); + ctor public FontConfig.Family(java.lang.String, android.text.FontConfig.Font[], java.lang.String, int); method public int describeContents(); - method public java.util.List<android.text.FontConfig.Font> getFonts(); + method public android.text.FontConfig.Font[] getFonts(); method public java.lang.String getLanguage(); method public java.lang.String getName(); - method public java.lang.String getVariant(); + method public int getVariant(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.text.FontConfig.Family> CREATOR; + field public static final int VARIANT_COMPACT = 1; // 0x1 + field public static final int VARIANT_DEFAULT = 0; // 0x0 + field public static final int VARIANT_ELEGANT = 2; // 0x2 } public static final class FontConfig.Font implements android.os.Parcelable { - ctor public FontConfig.Font(java.lang.String, int, java.util.List<android.text.FontConfig.Axis>, int, boolean); - ctor public FontConfig.Font(android.text.FontConfig.Font); method public int describeContents(); - method public java.util.List<android.text.FontConfig.Axis> getAxes(); + method public android.text.FontConfig.Axis[] getAxes(); method public android.os.ParcelFileDescriptor getFd(); method public java.lang.String getFontName(); method public int getTtcIndex(); diff --git a/api/system-current.txt b/api/system-current.txt index 883eba4ce7cf..827b46ce7746 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -44355,11 +44355,10 @@ package android.text { } public final class FontConfig implements android.os.Parcelable { - ctor public FontConfig(); - ctor public FontConfig(android.text.FontConfig); + ctor public FontConfig(android.text.FontConfig.Family[], android.text.FontConfig.Alias[]); method public int describeContents(); - method public java.util.List<android.text.FontConfig.Alias> getAliases(); - method public java.util.List<android.text.FontConfig.Family> getFamilies(); + method public android.text.FontConfig.Alias[] getAliases(); + method public android.text.FontConfig.Family[] getFamilies(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.text.FontConfig> CREATOR; } @@ -44384,22 +44383,22 @@ package android.text { } public static final class FontConfig.Family implements android.os.Parcelable { - ctor public FontConfig.Family(java.lang.String, java.util.List<android.text.FontConfig.Font>, java.lang.String, java.lang.String); - ctor public FontConfig.Family(android.text.FontConfig.Family); + ctor public FontConfig.Family(java.lang.String, android.text.FontConfig.Font[], java.lang.String, int); method public int describeContents(); - method public java.util.List<android.text.FontConfig.Font> getFonts(); + method public android.text.FontConfig.Font[] getFonts(); method public java.lang.String getLanguage(); method public java.lang.String getName(); - method public java.lang.String getVariant(); + method public int getVariant(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.text.FontConfig.Family> CREATOR; + field public static final int VARIANT_COMPACT = 1; // 0x1 + field public static final int VARIANT_DEFAULT = 0; // 0x0 + field public static final int VARIANT_ELEGANT = 2; // 0x2 } public static final class FontConfig.Font implements android.os.Parcelable { - ctor public FontConfig.Font(java.lang.String, int, java.util.List<android.text.FontConfig.Axis>, int, boolean); - ctor public FontConfig.Font(android.text.FontConfig.Font); method public int describeContents(); - method public java.util.List<android.text.FontConfig.Axis> getAxes(); + method public android.text.FontConfig.Axis[] getAxes(); method public android.os.ParcelFileDescriptor getFd(); method public java.lang.String getFontName(); method public int getTtcIndex(); diff --git a/api/test-current.txt b/api/test-current.txt index f5883c993648..04f4f21e095f 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -41083,11 +41083,10 @@ package android.text { } public final class FontConfig implements android.os.Parcelable { - ctor public FontConfig(); - ctor public FontConfig(android.text.FontConfig); + ctor public FontConfig(android.text.FontConfig.Family[], android.text.FontConfig.Alias[]); method public int describeContents(); - method public java.util.List<android.text.FontConfig.Alias> getAliases(); - method public java.util.List<android.text.FontConfig.Family> getFamilies(); + method public android.text.FontConfig.Alias[] getAliases(); + method public android.text.FontConfig.Family[] getFamilies(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.text.FontConfig> CREATOR; } @@ -41112,22 +41111,22 @@ package android.text { } public static final class FontConfig.Family implements android.os.Parcelable { - ctor public FontConfig.Family(java.lang.String, java.util.List<android.text.FontConfig.Font>, java.lang.String, java.lang.String); - ctor public FontConfig.Family(android.text.FontConfig.Family); + ctor public FontConfig.Family(java.lang.String, android.text.FontConfig.Font[], java.lang.String, int); method public int describeContents(); - method public java.util.List<android.text.FontConfig.Font> getFonts(); + method public android.text.FontConfig.Font[] getFonts(); method public java.lang.String getLanguage(); method public java.lang.String getName(); - method public java.lang.String getVariant(); + method public int getVariant(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.text.FontConfig.Family> CREATOR; + field public static final int VARIANT_COMPACT = 1; // 0x1 + field public static final int VARIANT_DEFAULT = 0; // 0x0 + field public static final int VARIANT_ELEGANT = 2; // 0x2 } public static final class FontConfig.Font implements android.os.Parcelable { - ctor public FontConfig.Font(java.lang.String, int, java.util.List<android.text.FontConfig.Axis>, int, boolean); - ctor public FontConfig.Font(android.text.FontConfig.Font); method public int describeContents(); - method public java.util.List<android.text.FontConfig.Axis> getAxes(); + method public android.text.FontConfig.Axis[] getAxes(); method public android.os.ParcelFileDescriptor getFd(); method public java.lang.String getFontName(); method public int getTtcIndex(); diff --git a/core/java/android/content/res/FontResourcesParser.java b/core/java/android/content/res/FontResourcesParser.java index 50fc3443f5a6..091cc263f5b4 100644 --- a/core/java/android/content/res/FontResourcesParser.java +++ b/core/java/android/content/res/FontResourcesParser.java @@ -16,7 +16,8 @@ package android.content.res; import com.android.internal.R; -import android.text.FontConfig; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.util.AttributeSet; import android.util.Xml; @@ -35,7 +36,81 @@ public class FontResourcesParser { private static final int NORMAL_WEIGHT = 400; private static final int ITALIC = 1; - public static FontConfig parse(XmlPullParser parser, Resources resources) + // A class represents single entry of font-family in xml file. + public interface FamilyResourceEntry {} + + // A class represents font provider based font-family element in xml file. + public static final class ProviderResourceEntry implements FamilyResourceEntry { + private final @NonNull String mProviderAuthority; + private final @NonNull String mProviderPackage; + private final @NonNull String mQuery; + + public ProviderResourceEntry(@NonNull String authority, @NonNull String pkg, + @NonNull String query) { + mProviderAuthority = authority; + mProviderPackage = pkg; + mQuery = query; + } + + public @NonNull String getAuthority() { + return mProviderAuthority; + } + + public @NonNull String getPackage() { + return mProviderPackage; + } + + public @NonNull String getQuery() { + return mQuery; + } + } + + // A class represents font element in xml file which points a file in resource. + public static final class FontFileResourceEntry { + private final @NonNull String mFileName; + private int mWeight; + private boolean mItalic; + private int mResourceId; + + public FontFileResourceEntry(@NonNull String fileName, int weight, boolean italic, + int resourceId) { + mFileName = fileName; + mWeight = weight; + mItalic = italic; + mResourceId = resourceId; + } + + public @NonNull String getFileName() { + return mFileName; + } + + public int getWeight() { + return mWeight; + } + + public boolean isItalic() { + return mItalic; + } + + public int getResourceId() { + return mResourceId; + } + } + + // A class represents file based font-family element in xml file. + public static final class FontFamilyFilesResourceEntry implements FamilyResourceEntry { + private final @NonNull FontFileResourceEntry[] mEntries; + + public FontFamilyFilesResourceEntry(@NonNull FontFileResourceEntry[] entries) { + mEntries = entries; + } + + public @NonNull FontFileResourceEntry[] getEntries() { + return mEntries; + } + } + + public static @Nullable FamilyResourceEntry parse(XmlPullParser parser, Resources resources) throws XmlPullParserException, IOException { int type; while ((type=parser.next()) != XmlPullParser.START_TAG @@ -49,21 +124,21 @@ public class FontResourcesParser { return readFamilies(parser, resources); } - private static FontConfig readFamilies(XmlPullParser parser, Resources resources) - throws XmlPullParserException, IOException { - FontConfig config = new FontConfig(); + private static @Nullable FamilyResourceEntry readFamilies(XmlPullParser parser, + Resources resources) throws XmlPullParserException, IOException { parser.require(XmlPullParser.START_TAG, null, "font-family"); String tag = parser.getName(); + FamilyResourceEntry result = null; if (tag.equals("font-family")) { - config.getFamilies().add(readFamily(parser, resources)); + return readFamily(parser, resources); } else { skip(parser); + return null; } - return config; } - private static FontConfig.Family readFamily(XmlPullParser parser, Resources resources) - throws XmlPullParserException, IOException { + private static @Nullable FamilyResourceEntry readFamily(XmlPullParser parser, + Resources resources) throws XmlPullParserException, IOException { AttributeSet attrs = Xml.asAttributeSet(parser); TypedArray array = resources.obtainAttributes(attrs, R.styleable.FontFamily); String authority = array.getString(R.styleable.FontFamily_fontProviderAuthority); @@ -74,9 +149,9 @@ public class FontResourcesParser { while (parser.next() != XmlPullParser.END_TAG) { skip(parser); } - return new FontConfig.Family(authority, providerPackage, query); + return new ProviderResourceEntry(authority, providerPackage, query); } - List<FontConfig.Font> fonts = new ArrayList<>(); + List<FontFileResourceEntry> fonts = new ArrayList<>(); while (parser.next() != XmlPullParser.END_TAG) { if (parser.getEventType() != XmlPullParser.START_TAG) continue; String tag = parser.getName(); @@ -86,10 +161,14 @@ public class FontResourcesParser { skip(parser); } } - return new FontConfig.Family(null, fonts, null, null); + if (fonts.isEmpty()) { + return null; + } + return new FontFamilyFilesResourceEntry(fonts.toArray( + new FontFileResourceEntry[fonts.size()])); } - private static FontConfig.Font readFont(XmlPullParser parser, Resources resources) + private static FontFileResourceEntry readFont(XmlPullParser parser, Resources resources) throws XmlPullParserException, IOException { AttributeSet attrs = Xml.asAttributeSet(parser); TypedArray array = resources.obtainAttributes(attrs, R.styleable.FontFamilyFont); @@ -101,7 +180,7 @@ public class FontResourcesParser { while (parser.next() != XmlPullParser.END_TAG) { skip(parser); } - return new FontConfig.Font(filename, 0, null, weight, isItalic, resourceId); + return new FontFileResourceEntry(filename, weight, isItalic, resourceId); } private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException { diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index 38efa4901553..949d64458ae5 100644 --- a/core/java/android/content/res/ResourcesImpl.java +++ b/core/java/android/content/res/ResourcesImpl.java @@ -769,8 +769,13 @@ public class ResourcesImpl { if (file.endsWith("xml")) { final XmlResourceParser rp = loadXmlResourceParser( file, id, value.assetCookie, "font"); - final FontConfig config = FontResourcesParser.parse(rp, wrapper); - return Typeface.createFromResources(config, mAssets, file); + final FontResourcesParser.FamilyResourceEntry familyEntry = + FontResourcesParser.parse(rp, wrapper); + if (familyEntry == null) { + Log.e(TAG, "Failed to find font-family tag"); + return null; + } + return Typeface.createFromResources(familyEntry, mAssets, file); } return Typeface.createFromResources(mAssets, file, value.assetCookie); } catch (XmlPullParserException e) { @@ -796,20 +801,23 @@ public class ResourcesImpl { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, file); try { + // TODO: Stop re-ussing font-family xml tag structure and use ResourceArray instead. final XmlResourceParser rp = loadXmlResourceParser( file, id, value.assetCookie, "font"); - final FontConfig config = FontResourcesParser.parse(rp, wrapper); - final List<FontConfig.Family> families = config.getFamilies(); - if (families == null || families.isEmpty()) { + final FontResourcesParser.FamilyResourceEntry familyEntry = + FontResourcesParser.parse(rp, wrapper); + if (familyEntry == null) { + Log.e(TAG, "failed to find font-family tag"); return; } - for (int j = 0; j < families.size(); j++) { - final FontConfig.Family family = families.get(j); - final List<FontConfig.Font> fonts = family.getFonts(); - for (int i = 0; i < fonts.size(); i++) { - int resourceId = fonts.get(i).getResourceId(); - wrapper.getFont(resourceId); - } + if (familyEntry instanceof FontResourcesParser.ProviderResourceEntry) { + throw new IllegalArgumentException("Provider based fonts can not be used."); + } + final FontResourcesParser.FontFamilyFilesResourceEntry filesEntry = + (FontResourcesParser.FontFamilyFilesResourceEntry) familyEntry; + for (FontResourcesParser.FontFileResourceEntry fileEntry : filesEntry.getEntries()) { + int resourceId = fileEntry.getResourceId(); + wrapper.getFont(resourceId); } } catch (XmlPullParserException e) { Log.e(TAG, "Failed to parse xml resource " + file, e); diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java index 1087851c853f..04596fa5aa3d 100644 --- a/core/java/android/text/FontConfig.java +++ b/core/java/android/text/FontConfig.java @@ -16,42 +16,57 @@ package android.text; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.Parcelable; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; +import java.lang.annotation.Retention; +import java.util.Arrays; + /** * Font configuration descriptions for System fonts. */ public final class FontConfig implements Parcelable { - private final List<Family> mFamilies = new ArrayList<>(); - private final List<Alias> mAliases = new ArrayList<>(); + private final @NonNull Family[] mFamilies; + private final @NonNull Alias[] mAliases; - public FontConfig() { + public FontConfig(@NonNull Family[] families, @NonNull Alias[] aliases) { + mFamilies = families; + mAliases = aliases; } - public FontConfig(FontConfig config) { - for (int i = 0; i < config.mFamilies.size(); i++) { - mFamilies.add(new Family(config.mFamilies.get(i))); + /** + * For duplicating file descriptors. + * + * Note that this copy constructor can not be usable for deep copy. + * @hide + */ + public FontConfig(@NonNull FontConfig config) { + mFamilies = new Family[config.mFamilies.length]; + for (int i = 0; i < config.mFamilies.length; ++i) { + mFamilies[i] = new Family(config.mFamilies[i]); } - mAliases.addAll(config.mAliases); + mAliases = Arrays.copyOf(config.mAliases, config.mAliases.length); } /** * Returns the ordered list of families included in the system fonts. */ - public List<Family> getFamilies() { + public @NonNull Family[] getFamilies() { return mFamilies; } /** * Returns the list of aliases defined for the font families in the system fonts. */ - public List<Alias> getAliases() { + public @NonNull Alias[] getAliases() { return mAliases; } @@ -59,33 +74,14 @@ public final class FontConfig implements Parcelable { * @hide */ public FontConfig(Parcel in) { - readFromParcel(in); + mFamilies = in.readTypedArray(Family.CREATOR); + mAliases = in.readTypedArray(Alias.CREATOR); } @Override public void writeToParcel(Parcel out, int flag) { - out.writeInt(mFamilies.size()); - for (int i = 0; i < mFamilies.size(); i++) { - mFamilies.get(i).writeToParcel(out, flag); - } - out.writeInt(mAliases.size()); - for (int i = 0; i < mAliases.size(); i++) { - mAliases.get(i).writeToParcel(out, flag); - } - } - - /** - * @hide - */ - public void readFromParcel(Parcel in) { - int size = in.readInt(); - for (int i = 0; i < size; i++) { - mFamilies.add(new Family(in)); - } - size = in.readInt(); - for (int i = 0; i < size; i++) { - mAliases.add(new Alias(in)); - } + out.writeTypedArray(mFamilies, flag); + out.writeTypedArray(mAliases, flag); } @Override @@ -164,36 +160,37 @@ public final class FontConfig implements Parcelable { * Class that holds information about a Font. */ public static final class Font implements Parcelable { - private String mFontName; + private final @NonNull String mFontName; private final int mTtcIndex; - private final List<Axis> mAxes; + private final @NonNull Axis[] mAxes; private final int mWeight; private final boolean mIsItalic; - private ParcelFileDescriptor mFd; - private final int mResourceId; + private @Nullable ParcelFileDescriptor mFd; /** * @hide */ - public Font(String fontName, int ttcIndex, List<Axis> axes, int weight, boolean isItalic, - int resourceId) { + public Font(@NonNull String fontName, int ttcIndex, @NonNull Axis[] axes, int weight, + boolean isItalic) { mFontName = fontName; mTtcIndex = ttcIndex; mAxes = axes; mWeight = weight; mIsItalic = isItalic; mFd = null; - mResourceId = resourceId; - } - - public Font(String fontName, int ttcIndex, List<Axis> axes, int weight, boolean isItalic) { - this(fontName, ttcIndex, axes, weight, isItalic, 0); } + /** + * This is for duplicating FileDescriptors. + * + * Note that this copy ctor doesn't deep copy the members. + * + * @hide + */ public Font(Font origin) { mFontName = origin.mFontName; mTtcIndex = origin.mTtcIndex; - mAxes = new ArrayList<>(origin.mAxes); + mAxes = origin.mAxes; mWeight = origin.mWeight; mIsItalic = origin.mIsItalic; if (origin.mFd != null) { @@ -203,24 +200,16 @@ public final class FontConfig implements Parcelable { e.printStackTrace(); } } - mResourceId = origin.mResourceId; } /** * Returns the name associated by the system to this font. */ - public String getFontName() { + public @NonNull String getFontName() { return mFontName; } /** - * @hide - */ - public void setFontName(String fontName) { - mFontName = fontName; - } - - /** * Returns the index to be used to access this font when accessing a TTC file. */ public int getTtcIndex() { @@ -230,7 +219,7 @@ public final class FontConfig implements Parcelable { /** * Returns the list of axes associated to this font. */ - public List<Axis> getAxes() { + public @NonNull Axis[] getAxes() { return mAxes; } @@ -251,35 +240,24 @@ public final class FontConfig implements Parcelable { /** * Returns a file descriptor to access the specified font. This should be closed after use. */ - public ParcelFileDescriptor getFd() { + public @Nullable ParcelFileDescriptor getFd() { return mFd; } /** * @hide */ - public void setFd(ParcelFileDescriptor fd) { + public void setFd(@NonNull ParcelFileDescriptor fd) { mFd = fd; } /** * @hide */ - public int getResourceId() { - return mResourceId; - } - - /** - * @hide - */ public Font(Parcel in) { mFontName = in.readString(); mTtcIndex = in.readInt(); - final int numAxes = in.readInt(); - mAxes = new ArrayList<>(); - for (int i = 0; i < numAxes; i++) { - mAxes.add(new Axis(in)); - } + mAxes = in.createTypedArray(Axis.CREATOR); mWeight = in.readInt(); mIsItalic = in.readInt() == 1; if (in.readInt() == 1) { /* has FD */ @@ -287,24 +265,19 @@ public final class FontConfig implements Parcelable { } else { mFd = null; } - mResourceId = in.readInt(); } @Override public void writeToParcel(Parcel out, int flag) { out.writeString(mFontName); out.writeInt(mTtcIndex); - out.writeInt(mAxes.size()); - for (int i = 0; i < mAxes.size(); i++) { - mAxes.get(i).writeToParcel(out, flag); - } + out.writeTypedArray(mAxes, flag); out.writeInt(mWeight); out.writeInt(mIsItalic ? 1 : 0); out.writeInt(mFd == null ? 0 : 1); if (mFd != null) { mFd.writeToParcel(out, flag); } - out.writeInt(mResourceId); } @Override @@ -329,27 +302,27 @@ public final class FontConfig implements Parcelable { * Class that holds information about a Font alias. */ public static final class Alias implements Parcelable { - private final String mName; - private final String mToName; + private final @NonNull String mName; + private final @NonNull String mToName; private final int mWeight; - public Alias(String name, String toName, int weight) { - this.mName = name; - this.mToName = toName; - this.mWeight = weight; + public Alias(@NonNull String name, @NonNull String toName, int weight) { + mName = name; + mToName = toName; + mWeight = weight; } /** * Returns the new name for the alias. */ - public String getName() { + public @NonNull String getName() { return mName; } /** * Returns the existing name to which this alias points to. */ - public String getToName() { + public @NonNull String getToName() { return mToName; } @@ -398,149 +371,110 @@ public final class FontConfig implements Parcelable { * Class that holds information about a Font family. */ public static final class Family implements Parcelable { - private final String mName; - private final List<Font> mFonts; - private final String mLanguage; - private final String mVariant; - private final String mProviderAuthority; - private final String mProviderPackage; - private final String mQuery; - - public Family(String name, List<Font> fonts, String language, String variant) { + private final @NonNull String mName; + private final @NonNull Font[] mFonts; + private final @NonNull String mLanguage; + + /** @hide */ + @Retention(SOURCE) + @IntDef({VARIANT_DEFAULT, VARIANT_COMPACT, VARIANT_ELEGANT}) + public @interface Variant {} + + /** + * Value for font variant. + * + * Indicates the font has no variant attribute. + */ + public static final int VARIANT_DEFAULT = 0; + + /** + * Value for font variant. + * + * Indicates the font is for compact variant. + * @see android.graphics.Paint#setElegantTextHeight + */ + public static final int VARIANT_COMPACT = 1; + + /** + * Value for font variant. + * + * Indiates the font is for elegant variant. + * @see android.graphics.Paint#setElegantTextHeight + */ + public static final int VARIANT_ELEGANT = 2; + + // Must be same with Minikin's variant values. + // See frameworks/minikin/include/minikin/FontFamily.h + private final @Variant int mVariant; + + public Family(@NonNull String name, @NonNull Font[] fonts, @NonNull String language, + @Variant int variant) { mName = name; mFonts = fonts; mLanguage = language; mVariant = variant; - mProviderAuthority = null; - mProviderPackage = null; - mQuery = null; } /** + * For duplicating file descriptor underlying Font object. + * + * This copy constructor is not for deep copying. * @hide */ - public Family(String providerAuthority, String providerPackage, String query) { - mName = null; - mFonts = null; - mLanguage = null; - mVariant = null; - mProviderAuthority = providerAuthority; - mProviderPackage = providerPackage; - mQuery = query; - } - public Family(Family origin) { mName = origin.mName; mLanguage = origin.mLanguage; mVariant = origin.mVariant; - mFonts = new ArrayList<>(); - for (int i = 0; i < origin.mFonts.size(); i++) { - mFonts.add(new Font(origin.mFonts.get(i))); + mFonts = new Font[origin.mFonts.length]; + for (int i = 0; i < origin.mFonts.length; ++i) { + mFonts[i] = new Font(origin.mFonts[i]); } - mProviderAuthority = origin.mProviderAuthority; - mProviderPackage = origin.mProviderPackage; - mQuery = origin.mQuery; } /** * Returns the name given by the system to this font family. */ - public String getName() { + public @Nullable String getName() { return mName; } /** * Returns the list of fonts included in this family. */ - public List<Font> getFonts() { + public @Nullable Font[] getFonts() { return mFonts; } /** * Returns the language for this family. May be null. */ - public String getLanguage() { + public @Nullable String getLanguage() { return mLanguage; } /** * Returns the font variant for this family, e.g. "elegant" or "compact". May be null. */ - public String getVariant() { + public @Variant int getVariant() { return mVariant; } /** * @hide */ - public String getProviderAuthority() { - return mProviderAuthority; - } - - /** - * @hide - */ - public String getProviderPackage() { - return mProviderPackage; - } - - /** - * @hide - */ - public String getQuery() { - return mQuery; - } - - /** - * @hide - */ public Family(Parcel in) { mName = in.readString(); - final int size = in.readInt(); - mFonts = new ArrayList<>(); - for (int i = 0; i < size; i++) { - mFonts.add(new Font(in)); - } + mFonts = in.readTypedArray(Font.CREATOR); mLanguage = in.readString(); - mVariant = in.readString(); - if (in.readInt() == 1) { - mProviderAuthority = in.readString(); - } else { - mProviderAuthority = null; - } - if (in.readInt() == 1) { - mProviderPackage = in.readString(); - } else { - mProviderPackage = null; - } - if (in.readInt() == 1) { - mQuery = in.readString(); - } else { - mQuery = null; - } + mVariant = in.readInt(); } @Override public void writeToParcel(Parcel out, int flag) { out.writeString(mName); - out.writeInt(mFonts.size()); - for (int i = 0; i < mFonts.size(); i++) { - mFonts.get(i).writeToParcel(out, flag); - } + out.writeTypedArray(mFonts, flag); out.writeString(mLanguage); - out.writeString(mVariant); - out.writeInt(mProviderAuthority == null ? 0 : 1); - if (mProviderAuthority != null) { - out.writeString(mProviderAuthority); - } - out.writeInt(mProviderPackage == null ? 0 : 1); - if (mProviderPackage != null) { - out.writeString(mProviderPackage); - } - out.writeInt(mQuery == null ? 0 : 1); - if (mQuery != null) { - out.writeString(mQuery); - } + out.writeInt(mVariant); } @Override diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index e3ac40c5da4e..0e06cd32161b 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -833,6 +833,7 @@ public abstract class LayoutInflater { final int depth = parser.getDepth(); int type; + boolean pendingRequestFocus = false; while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { @@ -844,7 +845,8 @@ public abstract class LayoutInflater { final String name = parser.getName(); if (TAG_REQUEST_FOCUS.equals(name)) { - parseRequestFocus(parser, parent); + pendingRequestFocus = true; + consumeChildElements(parser); } else if (TAG_TAG.equals(name)) { parseViewTag(parser, parent, attrs); } else if (TAG_INCLUDE.equals(name)) { @@ -863,23 +865,16 @@ public abstract class LayoutInflater { } } + if (pendingRequestFocus) { + parent.restoreDefaultFocus(); + } + if (finishInflate) { parent.onFinishInflate(); } } /** - * Parses a <code><request-focus></code> element and requests focus on - * the containing View. - */ - private void parseRequestFocus(XmlPullParser parser, View view) - throws XmlPullParserException, IOException { - view.requestFocus(); - - consumeChildElements(parser); - } - - /** * Parses a <code><tag></code> element and sets a keyed tag on the * containing View. */ diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 580888c4c3bc..ed4238501c5a 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -164,6 +164,17 @@ public final class ViewRootImpl implements ViewParent, static final ArrayList<ComponentCallbacks> sConfigCallbacks = new ArrayList(); /** + * Signals that compatibility booleans have been initialized according to + * target SDK versions. + */ + private static boolean sCompatibilityDone = false; + + /** + * Always assign focus if a focusable View is available. + */ + private static boolean sAlwaysAssignFocus; + + /** * This list must only be modified by the main thread, so a lock is only needed when changing * the list or when accessing the list from a non-main thread. */ @@ -451,6 +462,13 @@ public final class ViewRootImpl implements ViewParent, mFallbackEventHandler = new PhoneFallbackEventHandler(context); mChoreographer = Choreographer.getInstance(); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); + + if (!sCompatibilityDone) { + sAlwaysAssignFocus = mTargetSdkVersion < Build.VERSION_CODES.O; + + sCompatibilityDone = true; + } + loadSystemProperties(); } @@ -2180,7 +2198,7 @@ public final class ViewRootImpl implements ViewParent, } } - if (mFirst) { + if (mFirst && sAlwaysAssignFocus) { // handle first focus request if (DEBUG_INPUT_RESIZE) Log.v(mTag, "First: mView.hasFocus()=" + mView.hasFocus()); @@ -3290,7 +3308,9 @@ public final class ViewRootImpl implements ViewParent, checkThread(); if (mView != null) { if (!mView.hasFocus()) { - v.requestFocus(); + if (sAlwaysAssignFocus) { + v.requestFocus(); + } } else { // the one case where will transfer focus away from the current one // is if the current view is a view group that prefers to give focus @@ -4463,9 +4483,7 @@ public final class ViewRootImpl implements ViewParent, return true; } } else { - // find the best view to give focus to in this non-touch-mode with no-focus - View v = focusSearch(null, direction); - if (v != null && v.requestFocus(direction)) { + if (mView.restoreDefaultFocus()) { return true; } } @@ -4475,9 +4493,10 @@ public final class ViewRootImpl implements ViewParent, private boolean performKeyboardGroupNavigation(int direction) { final View focused = mView.findFocus(); - View cluster = focused != null - ? focused.keyboardNavigationClusterSearch(null, direction) - : keyboardNavigationClusterSearch(null, direction); + if (focused == null && mView.restoreDefaultFocus()) { + return true; + } + View cluster = focused.keyboardNavigationClusterSearch(null, direction); // Since requestFocus only takes "real" focus directions (and therefore also // restoreFocusInCluster), convert forward/backward focus into FOCUS_DOWN. diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java index c95a1fb966f5..06ac8699f864 100644 --- a/core/java/android/view/textclassifier/TextClassifierImpl.java +++ b/core/java/android/view/textclassifier/TextClassifierImpl.java @@ -121,8 +121,8 @@ final class TextClassifierImpl implements TextClassifier { .classifyText(text.toString(), startIndex, endIndex); if (results.length > 0) { // TODO: Added this log for debug only. Remove before release. - Log.d(LOG_TAG, - String.format("Classification type: %s", results[0].mCollection)); + Log.d(LOG_TAG, String.format( + "Classification type: %s", getHighestScoringType(results))); return createClassificationResult(results, classified); } } @@ -188,7 +188,7 @@ final class TextClassifierImpl implements TextClassifier { builder.setEntityType(classifications[i].mCollection, classifications[i].mScore); } - final String type = classifications[0].mCollection; + final String type = getHighestScoringType(classifications); final Intent intent = IntentFactory.create(mContext, type, text.toString()); final PackageManager pm; final ResolveInfo resolveInfo; @@ -226,6 +226,23 @@ final class TextClassifierImpl implements TextClassifier { return builder.build(); } + private static String getHighestScoringType(SmartSelection.ClassificationResult[] types) { + if (types.length < 1) { + return ""; + } + + String type = types[0].mCollection; + float highestScore = types[0].mScore; + final int size = types.length; + for (int i = 1; i < size; i++) { + if (types[i].mScore > highestScore) { + type = types[i].mCollection; + highestScore = types[i].mScore; + } + } + return type; + } + /** * @throws IllegalArgumentException if text is null; startIndex is negative; * endIndex is greater than text.length() or is not greater than startIndex @@ -265,7 +282,7 @@ final class TextClassifierImpl implements TextClassifier { final SmartSelection.ClassificationResult[] results = smartSelection.classifyText(text, selectionStart, selectionEnd); if (results.length > 0) { - final String type = results[0].mCollection; + final String type = getHighestScoringType(results); if (matches(type, linkMask)) { final Intent intent = IntentFactory.create( context, type, text.substring(selectionStart, selectionEnd)); diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java index 3ac5a72e087b..83cc9f09e8ed 100644 --- a/core/java/com/android/internal/content/FileSystemProvider.java +++ b/core/java/com/android/internal/content/FileSystemProvider.java @@ -18,6 +18,7 @@ package com.android.internal.content; import android.annotation.CallSuper; import android.content.ContentResolver; +import android.content.ContentValues; import android.content.Intent; import android.content.res.AssetFileDescriptor; import android.database.Cursor; @@ -157,10 +158,9 @@ public abstract class FileSystemProvider extends DocumentsProvider { if (!before.renameTo(after)) { throw new IllegalStateException("Failed to rename to " + after); } - removeFromMediaStore(visibleFileBefore); final String afterDocId = getDocIdForFile(after); - scanFile(getFileForDocId(afterDocId, true)); + moveInMediaStore(visibleFileBefore, getFileForDocId(afterDocId, true)); if (!TextUtils.equals(docId, afterDocId)) { return afterDocId; @@ -170,22 +170,6 @@ public abstract class FileSystemProvider extends DocumentsProvider { } @Override - public void deleteDocument(String docId) throws FileNotFoundException { - final File file = getFileForDocId(docId); - final File visibleFile = getFileForDocId(docId, true); - - final boolean isDirectory = file.isDirectory(); - if (isDirectory) { - FileUtils.deleteContents(file); - } - if (!file.delete()) { - throw new IllegalStateException("Failed to delete " + file); - } - - removeFromMediaStore(visibleFile); - } - - @Override public String moveDocument(String sourceDocumentId, String sourceParentDocumentId, String targetParentDocumentId) throws FileNotFoundException { @@ -200,22 +184,56 @@ public abstract class FileSystemProvider extends DocumentsProvider { throw new IllegalStateException("Failed to move to " + after); } - // Notify media store to update its content - removeFromMediaStore(visibleFileBefore); final String docId = getDocIdForFile(after); - scanFile(getFileForDocId(docId, true)); + moveInMediaStore(visibleFileBefore, getFileForDocId(docId, true)); return docId; } - private void removeFromMediaStore(File visibleFile) throws FileNotFoundException { + private void moveInMediaStore(File oldVisibleFile, File newVisibleFile) { + if (newVisibleFile != null) { + final ContentResolver resolver = getContext().getContentResolver(); + final Uri externalUri = MediaStore.Files.getContentUri("external"); + + ContentValues values = new ContentValues(); + values.put(MediaStore.Files.FileColumns.DATA, newVisibleFile.getAbsolutePath()); + + // Logic borrowed from MtpDatabase. + // note - we are relying on a special case in MediaProvider.update() to update + // the paths for all children in the case where this is a directory. + final String path = oldVisibleFile.getAbsolutePath(); + resolver.update(externalUri, + values, + "_data LIKE ? AND lower(_data)=lower(?)", + new String[] { path, path }); + } + } + + @Override + public void deleteDocument(String docId) throws FileNotFoundException { + final File file = getFileForDocId(docId); + final File visibleFile = getFileForDocId(docId, true); + + final boolean isDirectory = file.isDirectory(); + if (isDirectory) { + FileUtils.deleteContents(file); + } + if (!file.delete()) { + throw new IllegalStateException("Failed to delete " + file); + } + + removeFromMediaStore(visibleFile, isDirectory); + } + + private void removeFromMediaStore(File visibleFile, boolean isFolder) + throws FileNotFoundException { if (visibleFile != null) { final ContentResolver resolver = getContext().getContentResolver(); final Uri externalUri = MediaStore.Files.getContentUri("external"); // Remove media store entries for any files inside this directory, using // path prefix match. Logic borrowed from MtpDatabase. - if (visibleFile.isDirectory()) { + if (isFolder) { final String path = visibleFile.getAbsolutePath() + "/"; resolver.delete(externalUri, "_data LIKE ?1 AND lower(substr(_data,1,?2))=lower(?3)", diff --git a/core/java/com/android/internal/policy/PipSnapAlgorithm.java b/core/java/com/android/internal/policy/PipSnapAlgorithm.java index ae31873492e9..95d714f1c3c7 100644 --- a/core/java/com/android/internal/policy/PipSnapAlgorithm.java +++ b/core/java/com/android/internal/policy/PipSnapAlgorithm.java @@ -321,7 +321,7 @@ public class PipSnapAlgorithm { stackBounds.top)); boundsOut.set(stackBounds); if (mIsMinimized) { - boundsOut.offsetTo(boundedLeft, boundsOut.top); + boundsOut.offsetTo(boundedLeft, boundedTop); return; } diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java index 79b0cd1aced8..818cc2c2421d 100644 --- a/core/java/com/android/internal/widget/FloatingToolbar.java +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -1163,21 +1163,21 @@ public final class FloatingToolbar { isLastItem && menuItemButtonWidth <= availableWidth - extraPadding; if (canFitWithOverflow || canFitNoOverflow) { if (isNewGroup) { - final View border = createBorder(mContext); - final int borderWidth = border.getLayoutParams().width; + final View divider = createDivider(mContext); + final int dividerWidth = divider.getLayoutParams().width; // Add extra padding to the end of the previous button. // Half of the extra padding (less borderWidth) goes to the previous button. View previousButton = mMainPanel.getChildAt(mMainPanel.getChildCount() - 1); final int prevPaddingEnd = previousButton.getPaddingEnd() - + extraPadding / 2 - borderWidth; + + extraPadding / 2 - dividerWidth; previousButton.setPaddingRelative( previousButton.getPaddingStart(), previousButton.getPaddingTop(), prevPaddingEnd, previousButton.getPaddingBottom()); final ViewGroup.LayoutParams prevParams = previousButton.getLayoutParams(); - prevParams.width += extraPadding / 2 - borderWidth; + prevParams.width += extraPadding / 2 - dividerWidth; previousButton.setLayoutParams(prevParams); // Add extra padding to the start of this button. @@ -1190,8 +1190,8 @@ public final class FloatingToolbar { menuItemButton.getPaddingEnd(), menuItemButton.getPaddingBottom()); - // Include a border. - mMainPanel.addView(border); + // Include a divider. + mMainPanel.addView(divider); } setButtonTagAndClickListener(menuItemButton, menuItem); @@ -1670,21 +1670,28 @@ public final class FloatingToolbar { return popupWindow; } - private static View createBorder(Context context) { + private static View createDivider(Context context) { // TODO: Inflate this instead. - View border = new View(context); + View divider = new View(context); + int _1dp = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 1, context.getResources().getDisplayMetrics()); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( _1dp, ViewGroup.LayoutParams.MATCH_PARENT); params.setMarginsRelative(0, _1dp * 10, 0, _1dp * 10); - border.setLayoutParams(params); - border.setBackgroundColor(Color.parseColor("#9E9E9E")); - border.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); - border.setEnabled(false); - border.setFocusable(false); - border.setContentDescription(null); - return border; + divider.setLayoutParams(params); + + TypedArray a = context.obtainStyledAttributes( + new TypedValue().data, new int[] { R.attr.floatingToolbarDividerColor }); + divider.setBackgroundColor(a.getColor(0, 0)); + a.recycle(); + + divider.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + divider.setEnabled(false); + divider.setFocusable(false); + divider.setContentDescription(null); + + return divider; } /** diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp index f85219453212..a8d683028c13 100755 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -453,7 +453,8 @@ bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int dst = dstBitmap.getAddr(x, y); SkColorSpace* colorSpace = dstBitmap.colorSpace(); - if (GraphicsJNI::isColorSpaceSRGB(colorSpace)) { + if (dstBitmap.colorType() == kRGBA_F16_SkColorType || + GraphicsJNI::isColorSpaceSRGB(colorSpace)) { // now copy/convert each scanline for (int y = 0; y < height; y++) { proc(dst, src, width, x, y); @@ -1267,7 +1268,8 @@ static jint Bitmap_getPixel(JNIEnv* env, jobject, jlong bitmapHandle, proc(dst, src, 1, bitmap.getColorTable()); SkColorSpace* colorSpace = bitmap.colorSpace(); - if (!GraphicsJNI::isColorSpaceSRGB(colorSpace)) { + if (bitmap.colorType() != kRGBA_F16_SkColorType && + !GraphicsJNI::isColorSpaceSRGB(colorSpace)) { auto sRGB = SkColorSpace::MakeSRGB(); auto xform = SkColorSpaceXform::New(colorSpace, sRGB.get()); xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, &dst[0], @@ -1299,7 +1301,8 @@ static void Bitmap_getPixels(JNIEnv* env, jobject, jlong bitmapHandle, SkColor* d = (SkColor*)dst + offset; SkColorSpace* colorSpace = bitmap.colorSpace(); - if (GraphicsJNI::isColorSpaceSRGB(colorSpace)) { + if (bitmap.colorType() == kRGBA_F16_SkColorType || + GraphicsJNI::isColorSpaceSRGB(colorSpace)) { while (--height >= 0) { proc(d, src, width, ctable); d += stride; @@ -1342,7 +1345,8 @@ static void Bitmap_setPixel(JNIEnv* env, jobject, jlong bitmapHandle, } SkColorSpace* colorSpace = bitmap.colorSpace(); - if (!GraphicsJNI::isColorSpaceSRGB(colorSpace)) { + if (bitmap.colorType() != kRGBA_F16_SkColorType && + !GraphicsJNI::isColorSpaceSRGB(colorSpace)) { auto sRGB = SkColorSpace::MakeSRGB(); auto xform = SkColorSpaceXform::New(sRGB.get(), colorSpace); xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, &color, diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp index 49024b6a0b5f..fb7c5c46843a 100644 --- a/core/jni/android/graphics/FontFamily.cpp +++ b/core/jni/android/graphics/FontFamily.cpp @@ -44,6 +44,7 @@ struct NativeFamilyBuilder { uint32_t langId; int variant; std::vector<minikin::Font> fonts; + std::vector<minikin::FontVariation> axes; }; static jlong FontFamily_initBuilder(JNIEnv* env, jobject clazz, jstring lang, jint variant) { @@ -155,32 +156,16 @@ static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong builderPtr, } static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong builderPtr, - jobject font, jint ttcIndex, jobject listOfAxis, jint weight, jboolean isItalic) { + jobject font, jint ttcIndex, jint weight, jboolean isItalic) { NPE_CHECK_RETURN_ZERO(env, font); + NativeFamilyBuilder* builder = reinterpret_cast<NativeFamilyBuilder*>(builderPtr); + // Declare axis native type. - std::unique_ptr<SkFontMgr::FontParameters::Axis[]> skiaAxes; - int skiaAxesLength = 0; - if (listOfAxis) { - ListHelper list(env, listOfAxis); - jint listSize = list.size(); - - skiaAxes.reset(new SkFontMgr::FontParameters::Axis[listSize]); - skiaAxesLength = listSize; - for (jint i = 0; i < listSize; ++i) { - jobject axisObject = list.get(i); - if (!axisObject) { - skiaAxes[i].fTag = 0; - skiaAxes[i].fStyleValue = 0; - continue; - } - AxisHelper axis(env, axisObject); - - jint tag = axis.getTag(); - jfloat stylevalue = axis.getStyleValue(); - skiaAxes[i].fTag = tag; - skiaAxes[i].fStyleValue = SkFloatToScalar(stylevalue); - } + std::vector<SkFontMgr::FontParameters::Axis> skiaAxes; + skiaAxes.reserve(builder->axes.size()); + for (const minikin::FontVariation& minikinAxis : builder->axes) { + skiaAxes.push_back({minikinAxis.axisTag, minikinAxis.value}); } const void* fontPtr = env->GetDirectBufferAddress(font); @@ -200,7 +185,7 @@ static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong SkFontMgr::FontParameters params; params.setCollectionIndex(ttcIndex); - params.setAxes(skiaAxes.get(), skiaAxesLength); + params.setAxes(skiaAxes.data(), skiaAxes.size()); sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault()); sk_sp<SkTypeface> face(fm->createFromStream(fontData.release(), params)); @@ -211,7 +196,6 @@ static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong std::shared_ptr<minikin::MinikinFont> minikinFont = std::make_shared<MinikinFontSkia>(std::move(face), fontPtr, fontSize, ttcIndex, std::vector<minikin::FontVariation>()); - NativeFamilyBuilder* builder = reinterpret_cast<NativeFamilyBuilder*>(builderPtr); builder->fonts.push_back(minikin::Font(std::move(minikinFont), minikin::FontStyle(weight / 100, isItalic))); return true; @@ -270,6 +254,11 @@ static jboolean FontFamily_addFontFromAssetManager(JNIEnv* env, jobject, jlong b return true; } +static void FontFamily_addAxisValue(jlong builderPtr, jint tag, jfloat value) { + NativeFamilyBuilder* builder = reinterpret_cast<NativeFamilyBuilder*>(builderPtr); + builder->axes.push_back({static_cast<minikin::AxisTag>(tag), value}); +} + /////////////////////////////////////////////////////////////////////////////// static const JNINativeMethod gFontFamilyMethods[] = { @@ -278,10 +267,11 @@ static const JNINativeMethod gFontFamilyMethods[] = { { "nAbort", "(J)V", (void*)FontFamily_abort }, { "nUnrefFamily", "(J)V", (void*)FontFamily_unref }, { "nAddFont", "(JLjava/nio/ByteBuffer;I)Z", (void*)FontFamily_addFont }, - { "nAddFontWeightStyle", "(JLjava/nio/ByteBuffer;ILjava/util/List;IZ)Z", + { "nAddFontWeightStyle", "(JLjava/nio/ByteBuffer;IIZ)Z", (void*)FontFamily_addFontWeightStyle }, { "nAddFontFromAssetManager", "(JLandroid/content/res/AssetManager;Ljava/lang/String;IZIZ)Z", (void*)FontFamily_addFontFromAssetManager }, + { "nAddAxisValue", "(JIF)V", (void*)FontFamily_addAxisValue }, }; int register_android_graphics_FontFamily(JNIEnv* env) diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index 18462376cd20..fa25a8f0c596 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -239,30 +239,38 @@ namespace PaintGlue { return result; } - static jint doTextRunCursor(JNIEnv *env, Paint* paint, const jchar *text, jint start, - jint count, jint flags, jint offset, jint opt) { + static jint doTextRunCursor(JNIEnv *env, Paint* paint, Typeface* typeface, const jchar *text, + jint start, jint count, jint dir, jint offset, jint opt) { minikin::GraphemeBreak::MoveOpt moveOpt = minikin::GraphemeBreak::MoveOpt(opt); - size_t result = minikin::GraphemeBreak::getTextRunCursor(text, start, count, offset, - moveOpt); + int bidiFlags = dir == 1 ? minikin::kBidi_Force_RTL : minikin::kBidi_Force_LTR; + std::unique_ptr<float[]> advancesArray(new float[count]); + MinikinUtils::measureText(paint, bidiFlags, typeface, text, start, count, start + count, + advancesArray.get()); + size_t result = minikin::GraphemeBreak::getTextRunCursor(advancesArray.get(), text, + start, count, offset, moveOpt); return static_cast<jint>(result); } - static jint getTextRunCursor___C(JNIEnv* env, jobject clazz, jlong paintHandle, jcharArray text, - jint contextStart, jint contextCount, jint dir, jint offset, jint cursorOpt) { + static jint getTextRunCursor___C(JNIEnv* env, jobject clazz, jlong paintHandle, + jlong typefaceHandle, jcharArray text, jint contextStart, jint contextCount, jint dir, + jint offset, jint cursorOpt) { Paint* paint = reinterpret_cast<Paint*>(paintHandle); + Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); jchar* textArray = env->GetCharArrayElements(text, nullptr); - jint result = doTextRunCursor(env, paint, textArray, contextStart, contextCount, dir, - offset, cursorOpt); + jint result = doTextRunCursor(env, paint, typeface, textArray, + contextStart, contextCount, dir, offset, cursorOpt); env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); return result; } - static jint getTextRunCursor__String(JNIEnv* env, jobject clazz, jlong paintHandle, jstring text, - jint contextStart, jint contextEnd, jint dir, jint offset, jint cursorOpt) { + static jint getTextRunCursor__String(JNIEnv* env, jobject clazz, jlong paintHandle, + jlong typefaceHandle, jstring text, jint contextStart, jint contextEnd, jint dir, + jint offset, jint cursorOpt) { Paint* paint = reinterpret_cast<Paint*>(paintHandle); + Typeface* typeface = reinterpret_cast<Typeface*>(typefaceHandle); const jchar* textArray = env->GetStringChars(text, nullptr); - jint result = doTextRunCursor(env, paint, textArray, contextStart, - contextEnd - contextStart, dir, offset, cursorOpt); + jint result = doTextRunCursor(env, paint, typeface, textArray, + contextStart, contextEnd - contextStart, dir, offset, cursorOpt); env->ReleaseStringChars(text, textArray); return result; } @@ -983,8 +991,8 @@ static const JNINativeMethod methods[] = { {"nGetTextAdvances","(JJLjava/lang/String;IIIII[FI)F", (void*) PaintGlue::getTextAdvances__StringIIIII_FI}, - {"nGetTextRunCursor", "(J[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C}, - {"nGetTextRunCursor", "(JLjava/lang/String;IIIII)I", + {"nGetTextRunCursor", "(JJ[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C}, + {"nGetTextRunCursor", "(JJLjava/lang/String;IIIII)I", (void*) PaintGlue::getTextRunCursor__String}, {"nGetTextPath", "(JJI[CIIFFJ)V", (void*) PaintGlue::getTextPath___C}, {"nGetTextPath", "(JJILjava/lang/String;IIFFJ)V", (void*) PaintGlue::getTextPath__String}, diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index c547ae52b958..b44ebece6a62 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -576,6 +576,7 @@ <attr name="floatingToolbarItemBackgroundDrawable" format="reference" /> <attr name="floatingToolbarOpenDrawable" format="reference" /> <attr name="floatingToolbarPopupBackgroundDrawable" format="reference" /> + <attr name="floatingToolbarDividerColor" format="reference" /> <!-- ============ --> <!-- Alert Dialog styles --> diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index 6015ed5259d8..f9fd57cf5df9 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -194,4 +194,8 @@ <color name="tooltip_background_dark">#e6616161</color> <color name="tooltip_background_light">#e6FFFFFF</color> + + <!-- FloatingToolbar --> + <color name="floating_popup_divider_dark">#2F2F2F</color> + <color name="floating_popup_divider_light">#E9E9E9</color> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 0c318cf5e355..26d71c35522d 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2425,6 +2425,7 @@ <java-symbol type="drawable" name="ft_avd_toarrow" /> <java-symbol type="drawable" name="ft_avd_toarrow_animation" /> <java-symbol type="drawable" name="ft_avd_tooverflow_animation" /> + <java-symbol type="attr" name="floatingToolbarDividerColor" /> <java-symbol type="string" name="date_picker_prev_month_button" /> <java-symbol type="string" name="date_picker_next_month_button" /> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index d100c63d4ec1..a661b070872d 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -398,6 +398,7 @@ please see themes_device_defaults.xml. <item name="floatingToolbarItemBackgroundDrawable">@drawable/item_background_material_dark</item> <item name="floatingToolbarOpenDrawable">@drawable/ic_menu_moreoverflow_material_dark</item> <item name="floatingToolbarPopupBackgroundDrawable">@drawable/floating_popup_background_dark</item> + <item name="floatingToolbarDividerColor">@color/floating_popup_divider_dark</item> <!-- SearchView attributes --> <item name="searchViewStyle">@style/Widget.Holo.SearchView</item> @@ -559,6 +560,7 @@ please see themes_device_defaults.xml. <item name="floatingToolbarItemBackgroundDrawable">@drawable/item_background_material_light</item> <item name="floatingToolbarOpenDrawable">@drawable/ic_menu_moreoverflow_material_light</item> <item name="floatingToolbarPopupBackgroundDrawable">@drawable/floating_popup_background_light</item> + <item name="floatingToolbarDividerColor">@color/floating_popup_divider_light</item> <!-- Tooltip popup colors --> <item name="tooltipForegroundColor">@color/bright_foreground_dark</item> diff --git a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java index 23d3aa5a64ab..82f46909cfa8 100644 --- a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java +++ b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java @@ -20,6 +20,11 @@ import static junit.framework.Assert.assertNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static android.content.res.FontResourcesParser.FamilyResourceEntry; +import static android.content.res.FontResourcesParser.ProviderResourceEntry; +import static android.content.res.FontResourcesParser.FontFileResourceEntry; +import static android.content.res.FontResourcesParser.FontFamilyFilesResourceEntry; + import android.app.Instrumentation; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; @@ -56,44 +61,40 @@ public class FontResourcesParserTest { public void testParse() throws XmlPullParserException, IOException { XmlResourceParser parser = mResources.getXml(R.font.samplexmlfont); - FontConfig result = FontResourcesParser.parse(parser, mResources); + FamilyResourceEntry result = FontResourcesParser.parse(parser, mResources); assertNotNull(result); - List<FontConfig.Family> families = result.getFamilies(); - assertEquals(1, families.size()); - List<FontConfig.Font> fonts = families.get(0).getFonts(); - assertEquals(4, fonts.size()); - FontConfig.Font font1 = fonts.get(0); + FontFamilyFilesResourceEntry filesEntry = (FontFamilyFilesResourceEntry) result; + FontFileResourceEntry[] fileEntries = filesEntry.getEntries(); + assertEquals(4, fileEntries.length); + FontFileResourceEntry font1 = fileEntries[0]; assertEquals(400, font1.getWeight()); assertEquals(false, font1.isItalic()); - assertEquals("res/font/samplefont.ttf", font1.getFontName()); - FontConfig.Font font2 = fonts.get(1); + assertEquals("res/font/samplefont.ttf", font1.getFileName()); + FontFileResourceEntry font2 = fileEntries[1]; assertEquals(400, font2.getWeight()); assertEquals(true, font2.isItalic()); - assertEquals("res/font/samplefont2.ttf", font2.getFontName()); - FontConfig.Font font3 = fonts.get(2); + assertEquals("res/font/samplefont2.ttf", font2.getFileName()); + FontFileResourceEntry font3 = fileEntries[2]; assertEquals(800, font3.getWeight()); assertEquals(false, font3.isItalic()); - assertEquals("res/font/samplefont3.ttf", font3.getFontName()); - FontConfig.Font font4 = fonts.get(3); + assertEquals("res/font/samplefont3.ttf", font3.getFileName()); + FontFileResourceEntry font4 = fileEntries[3]; assertEquals(800, font4.getWeight()); assertEquals(true, font4.isItalic()); - assertEquals("res/font/samplefont4.ttf", font4.getFontName()); + assertEquals("res/font/samplefont4.ttf", font4.getFileName()); } @Test public void testParseDownloadableFont() throws IOException, XmlPullParserException { XmlResourceParser parser = mResources.getXml(R.font.samplexmldownloadedfont); - FontConfig result = FontResourcesParser.parse(parser, mResources); + FamilyResourceEntry result = FontResourcesParser.parse(parser, mResources); assertNotNull(result); - List<FontConfig.Family> families = result.getFamilies(); - assertEquals(1, families.size()); - FontConfig.Family family = families.get(0); - assertEquals("com.example.test.fontprovider.authority", family.getProviderAuthority()); - assertEquals("com.example.test.fontprovider.package", family.getProviderPackage()); - assertEquals("MyRequestedFont", family.getQuery()); - assertNull(family.getFonts()); + ProviderResourceEntry providerEntry = (ProviderResourceEntry) result; + assertEquals("com.example.test.fontprovider.authority", providerEntry.getAuthority()); + assertEquals("com.example.test.fontprovider.package", providerEntry.getPackage()); + assertEquals("MyRequestedFont", providerEntry.getQuery()); } } diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 3d5ba7938b31..ed587bbaed24 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -791,12 +791,12 @@ public final class Bitmap implements Parcelable { int neww = width; int newh = height; - Canvas canvas = new Canvas(); Bitmap bitmap; Paint paint; Rect srcR = new Rect(x, y, x + width, y + height); RectF dstR = new RectF(0, 0, width, height); + RectF deviceR = new RectF(); Config newConfig = Config.ARGB_8888; final Config config = source.getConfig(); @@ -827,7 +827,6 @@ public final class Bitmap implements Parcelable { } else { final boolean transformed = !m.rectStaysRect(); - RectF deviceR = new RectF(); m.mapRect(deviceR, dstR); neww = Math.round(deviceR.width()); @@ -841,9 +840,6 @@ public final class Bitmap implements Parcelable { } bitmap = createBitmap(neww, newh, transformedConfig, transformed || source.hasAlpha()); - canvas.translate(-deviceR.left, -deviceR.top); - canvas.concat(m); - paint = new Paint(); paint.setFilterBitmap(filter); if (transformed) { @@ -857,7 +853,9 @@ public final class Bitmap implements Parcelable { bitmap.setHasAlpha(source.hasAlpha()); bitmap.setPremultiplied(source.mRequestPremultiplied); - canvas.setBitmap(bitmap); + Canvas canvas = new Canvas(bitmap); + canvas.translate(-deviceR.left, -deviceR.top); + canvas.concat(m); canvas.drawBitmap(source, srcR, dstR, paint); canvas.setBitmap(null); if (isHardware) { diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java index 317f232ef7ec..16fc2b143964 100644 --- a/graphics/java/android/graphics/FontFamily.java +++ b/graphics/java/android/graphics/FontFamily.java @@ -25,7 +25,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; -import java.util.List; /** * A family of typefaces with different styles. @@ -48,14 +47,8 @@ public class FontFamily { mBuilderPtr = nInitBuilder(null, 0); } - public FontFamily(String lang, String variant) { - int varEnum = 0; - if ("compact".equals(variant)) { - varEnum = 1; - } else if ("elegant".equals(variant)) { - varEnum = 2; - } - mBuilderPtr = nInitBuilder(lang, varEnum); + public FontFamily(String lang, int variant) { + mBuilderPtr = nInitBuilder(lang, variant); } public void freeze() { @@ -103,12 +96,15 @@ public class FontFamily { } } - public boolean addFontWeightStyle(ByteBuffer font, int ttcIndex, List<FontConfig.Axis> axes, + public boolean addFontWeightStyle(ByteBuffer font, int ttcIndex, FontConfig.Axis[] axes, int weight, boolean style) { if (mBuilderPtr == 0) { throw new IllegalStateException("Unable to call addFontWeightStyle after freezing."); } - return nAddFontWeightStyle(mBuilderPtr, font, ttcIndex, axes, weight, style); + for (FontConfig.Axis axis : axes) { + nAddAxisValue(mBuilderPtr, axis.getTag(), axis.getStyleValue()); + } + return nAddFontWeightStyle(mBuilderPtr, font, ttcIndex, weight, style); } /** @@ -143,8 +139,11 @@ public class FontFamily { private static native void nUnrefFamily(long nativePtr); private static native boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex); private static native boolean nAddFontWeightStyle(long builderPtr, ByteBuffer font, - int ttcIndex, List<FontConfig.Axis> listOfAxis, - int weight, boolean isItalic); + int ttcIndex, int weight, boolean isItalic); private static native boolean nAddFontFromAssetManager(long builderPtr, AssetManager mgr, String path, int cookie, boolean isAsset, int weight, boolean isItalic); + + // The added axis values are only valid for the next nAddFont* method call. + @CriticalNative + private static native void nAddAxisValue(long builderPtr, int tag, float value); } diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java index b757842c4f3f..1b6969f96f82 100644 --- a/graphics/java/android/graphics/FontListParser.java +++ b/graphics/java/android/graphics/FontListParser.java @@ -116,20 +116,23 @@ public class FontListParser { private static FontConfig readFamilies(XmlPullParser parser) throws XmlPullParserException, IOException { - FontConfig config = new FontConfig(); + List<FontConfig.Family> families = new ArrayList<>(); + List<FontConfig.Alias> aliases = new ArrayList<>(); + parser.require(XmlPullParser.START_TAG, null, "familyset"); while (parser.next() != XmlPullParser.END_TAG) { if (parser.getEventType() != XmlPullParser.START_TAG) continue; String tag = parser.getName(); if (tag.equals("family")) { - config.getFamilies().add(readFamily(parser)); + families.add(readFamily(parser)); } else if (tag.equals("alias")) { - config.getAliases().add(readAlias(parser)); + aliases.add(readAlias(parser)); } else { skip(parser); } } - return config; + return new FontConfig(families.toArray(new FontConfig.Family[families.size()]), + aliases.toArray(new FontConfig.Alias[aliases.size()])); } private static FontConfig.Family readFamily(XmlPullParser parser) @@ -147,7 +150,16 @@ public class FontListParser { skip(parser); } } - return new FontConfig.Family(name, fonts, lang, variant); + int intVariant = FontConfig.Family.VARIANT_DEFAULT; + if (variant != null) { + if (variant.equals("compact")) { + intVariant = FontConfig.Family.VARIANT_COMPACT; + } else if (variant.equals("elegant")) { + intVariant = FontConfig.Family.VARIANT_ELEGANT; + } + } + return new FontConfig.Family(name, fonts.toArray(new FontConfig.Font[fonts.size()]), lang, + intVariant); } /** Matches leading and trailing XML whitespace. */ @@ -177,7 +189,8 @@ public class FontListParser { } String fullFilename = "/system/fonts/" + FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll(""); - return new FontConfig.Font(fullFilename, index, axes, weight, isItalic); + return new FontConfig.Font(fullFilename, index, + axes.toArray(new FontConfig.Axis[axes.size()]), weight, isItalic); } /** The 'tag' attribute value is read as four character values between U+0020 and U+007E diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index b1d51ec2d92b..7ca4615434f5 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -2294,7 +2294,7 @@ public class Paint { throw new IndexOutOfBoundsException(); } - return nGetTextRunCursor(mNativePaint, text, + return nGetTextRunCursor(mNativePaint, mNativeTypeface, text, contextStart, contextLength, dir, offset, cursorOpt); } @@ -2380,7 +2380,7 @@ public class Paint { throw new IndexOutOfBoundsException(); } - return nGetTextRunCursor(mNativePaint, text, + return nGetTextRunCursor(mNativePaint, mNativeTypeface, text, contextStart, contextEnd, dir, offset, cursorOpt); } @@ -2686,9 +2686,9 @@ public class Paint { private static native float nGetTextAdvances(long paintPtr, long typefacePtr, String text, int start, int end, int contextStart, int contextEnd, int bidiFlags, float[] advances, int advancesIndex); - private native int nGetTextRunCursor(long paintPtr, char[] text, + private native int nGetTextRunCursor(long paintPtr, long typefacePtr, char[] text, int contextStart, int contextLength, int dir, int offset, int cursorOpt); - private native int nGetTextRunCursor(long paintPtr, String text, + private native int nGetTextRunCursor(long paintPtr, long typefacePtr, String text, int contextStart, int contextEnd, int dir, int offset, int cursorOpt); private static native void nGetTextPath(long paintPtr, long typefacePtr, int bidiFlags, char[] text, int index, int count, float x, float y, long path); diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 6de19cb0f3b2..95577caf65a8 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -16,6 +16,11 @@ package android.graphics; +import static android.content.res.FontResourcesParser.ProviderResourceEntry; +import static android.content.res.FontResourcesParser.FontFileResourceEntry; +import static android.content.res.FontResourcesParser.FontFamilyFilesResourceEntry; +import static android.content.res.FontResourcesParser.FamilyResourceEntry; + import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -161,46 +166,35 @@ public class Typeface { * Used by Resources to load a font resource of type xml. */ @Nullable - public static Typeface createFromResources(FontConfig config, AssetManager mgr, String path) { + public static Typeface createFromResources( + FamilyResourceEntry entry, AssetManager mgr, String path) { if (sFallbackFonts != null) { Typeface typeface = findFromCache(mgr, path); if (typeface != null) return typeface; - List<FontConfig.Family> families = config.getFamilies(); - if (families == null || families.isEmpty()) { - throw new RuntimeException( - "Font resource " + path + " contained no font families."); - } - if (families.size() > 1) { - throw new RuntimeException( - "Font resource " + path + " contained more than one family."); - } - FontConfig.Family family = families.get(0); - if (family.getProviderAuthority() != null && family.getQuery() != null) { + if (entry instanceof ProviderResourceEntry) { + final ProviderResourceEntry providerEntry = (ProviderResourceEntry) entry; // Downloadable font - typeface = findFromCache( - family.getProviderAuthority(), family.getQuery()); + typeface = findFromCache(providerEntry.getAuthority(), providerEntry.getQuery()); if (typeface != null) { return typeface; } // Downloaded font and it wasn't cached, request it again and return a // default font instead (nothing we can do now). - create(new FontRequest(family.getProviderAuthority(), family.getProviderPackage(), - family.getQuery()), NO_OP_REQUEST_CALLBACK); + create(new FontRequest(providerEntry.getAuthority(), providerEntry.getPackage(), + providerEntry.getQuery()), NO_OP_REQUEST_CALLBACK); return DEFAULT; } + // family is FontFamilyFilesResourceEntry + final FontFamilyFilesResourceEntry filesEntry = + (FontFamilyFilesResourceEntry) entry; + FontFamily fontFamily = new FontFamily(); - List<FontConfig.Font> fonts = family.getFonts(); - if (fonts == null || fonts.isEmpty()) { - throw new RuntimeException("Font resource " + path + " contained no fonts."); - } - for (int i = 0; i < fonts.size(); i++) { - FontConfig.Font font = fonts.get(i); - // TODO: Use style and weight info - if (!fontFamily.addFontFromAssetManager(mgr, font.getFontName(), - 0 /* resourceCookie */, false /* isAsset */, font.getWeight(), - font.isItalic())) { + for (final FontFileResourceEntry fontFile : filesEntry.getEntries()) { + if (!fontFamily.addFontFromAssetManager(mgr, fontFile.getFileName(), + 0 /* resourceCookie */, false /* isAsset */, fontFile.getWeight(), + fontFile.isItalic())) { return null; } } @@ -677,8 +671,8 @@ public class Typeface { List<FontFamily> familyList = new ArrayList<FontFamily>(); // Note that the default typeface is always present in the fallback list; // this is an enhancement from pre-Minikin behavior. - for (int i = 0; i < fontConfig.getFamilies().size(); i++) { - FontConfig.Family f = fontConfig.getFamilies().get(i); + for (int i = 0; i < fontConfig.getFamilies().length; i++) { + FontConfig.Family f = fontConfig.getFamilies()[i]; if (i == 0 || f.getName() == null) { familyList.add(makeFamilyFromParsed(f, bufferForPath)); } @@ -687,9 +681,9 @@ public class Typeface { setDefault(Typeface.createFromFamilies(sFallbackFonts)); Map<String, Typeface> systemFonts = new HashMap<String, Typeface>(); - for (int i = 0; i < fontConfig.getFamilies().size(); i++) { + for (int i = 0; i < fontConfig.getFamilies().length; i++) { Typeface typeface; - FontConfig.Family f = fontConfig.getFamilies().get(i); + FontConfig.Family f = fontConfig.getFamilies()[i]; if (f.getName() != null) { if (i == 0) { // The first entry is the default typeface; no sense in diff --git a/media/mca/filterfw/jni/jni_util.h b/media/mca/filterfw/jni/jni_util.h index 803ed29bdf33..9b57958c4473 100644 --- a/media/mca/filterfw/jni/jni_util.h +++ b/media/mca/filterfw/jni/jni_util.h @@ -198,7 +198,8 @@ class ObjectPool { CObjMap objects_; FlagMap owns_; - DISALLOW_COPY_AND_ASSIGN(ObjectPool); + ObjectPool(const ObjectPool&) = delete; + ObjectPool& operator=(const ObjectPool&) = delete; }; template<typename T> ObjectPool<T>* ObjectPool<T>::instance_ = NULL; diff --git a/media/mca/filterfw/native/Android.mk b/media/mca/filterfw/native/Android.mk index 2e900fe29e38..feaefcbad6c5 100644 --- a/media/mca/filterfw/native/Android.mk +++ b/media/mca/filterfw/native/Android.mk @@ -41,7 +41,11 @@ LOCAL_EXPORT_LDLIBS := -llog -lgcc LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code -LOCAL_STATIC_LIBRARIES := libarect +LOCAL_STATIC_LIBRARIES := \ + libarect \ + +LOCAL_SHARED_LIBRARIES += \ + libgui \ # TODO: Build a shared library as well? include $(BUILD_STATIC_LIBRARY) diff --git a/media/mca/filterfw/native/base/utilities.h b/media/mca/filterfw/native/base/utilities.h index 6bb3b7f7c9cf..2818f7222dd3 100644 --- a/media/mca/filterfw/native/base/utilities.h +++ b/media/mca/filterfw/native/base/utilities.h @@ -23,18 +23,6 @@ namespace android { namespace filterfw { -// Convenience Macro to make copy constructor and assignment operator private -// (thereby disallowing copying and assigning). -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - -// A macro to disallow all the implicit constructors, namely the -// default constructor, copy constructor and operator= functions. -#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName(); \ - DISALLOW_COPY_AND_ASSIGN(TypeName) - // STLDeleteContainerPointers() // For a range within a container of pointers, calls delete // (non-array version) on these pointers. diff --git a/media/mca/filterfw/native/core/gl_env.h b/media/mca/filterfw/native/core/gl_env.h index 04453016dc93..6af91af6f6c1 100644 --- a/media/mca/filterfw/native/core/gl_env.h +++ b/media/mca/filterfw/native/core/gl_env.h @@ -256,7 +256,8 @@ class GLEnv { std::map<int, ShaderProgram*> attached_shaders_; std::map<int, VertexFrame*> attached_vframes_; - DISALLOW_COPY_AND_ASSIGN(GLEnv); + GLEnv(const GLEnv&) = delete; + GLEnv& operator=(const GLEnv&) = delete; }; } // namespace filterfw diff --git a/media/mca/filterfw/native/core/native_frame.h b/media/mca/filterfw/native/core/native_frame.h index 2da557dec000..fd5216542910 100644 --- a/media/mca/filterfw/native/core/native_frame.h +++ b/media/mca/filterfw/native/core/native_frame.h @@ -76,7 +76,8 @@ class NativeFrame { // Capacity of data buffer in bytes. int capacity_; - DISALLOW_COPY_AND_ASSIGN(NativeFrame); + NativeFrame(const NativeFrame&) = delete; + NativeFrame& operator=(const NativeFrame&) = delete; }; } // namespace filterfw diff --git a/media/mca/filterfw/native/core/native_program.h b/media/mca/filterfw/native/core/native_program.h index ce704af67aa8..e39afc9931ae 100644 --- a/media/mca/filterfw/native/core/native_program.h +++ b/media/mca/filterfw/native/core/native_program.h @@ -75,7 +75,8 @@ class NativeProgram { // Pointer to user data void* user_data_; - DISALLOW_COPY_AND_ASSIGN(NativeProgram); + NativeProgram(const NativeProgram&) = delete; + NativeProgram& operator=(const NativeProgram&) = delete; }; } // namespace filterfw diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml index 6c06d05e100b..9374d522707b 100644 --- a/packages/SettingsProvider/AndroidManifest.xml +++ b/packages/SettingsProvider/AndroidManifest.xml @@ -17,6 +17,7 @@ android:multiprocess="false" android:exported="true" android:singleUser="true" - android:initOrder="100" /> + android:initOrder="100" + android:visibleToInstantApps="true" /> </application> </manifest> diff --git a/packages/SystemUI/res/layout/pip_menu_activity.xml b/packages/SystemUI/res/layout/pip_menu_activity.xml index 5e49d058cd84..c6837fa30925 100644 --- a/packages/SystemUI/res/layout/pip_menu_activity.xml +++ b/packages/SystemUI/res/layout/pip_menu_activity.xml @@ -15,50 +15,55 @@ --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/menu" + android:id="@+id/background" android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="#4D000000"> - <!-- The above background is only for the dismiss button ripple to show. --> + android:layout_height="match_parent"> - <ImageView - android:id="@+id/dismiss" - android:layout_width="@dimen/pip_action_size" - android:layout_height="@dimen/pip_action_size" - android:layout_gravity="top|end" - android:padding="@dimen/pip_action_padding" - android:contentDescription="@string/pip_phone_close" - android:src="@drawable/ic_close_white" - android:background="?android:selectableItemBackgroundBorderless" /> + <!-- Menu layout --> + <FrameLayout + android:id="@+id/menu_container" + android:layout_width="match_parent" + android:layout_height="match_parent"> - <!-- The margins for this container is calculated in the code depending on whether the - actions_container is visible. --> - <FrameLayout - android:id="@+id/expand_container" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <ImageView - android:id="@+id/expand_button" - android:layout_width="60dp" - android:layout_height="60dp" - android:layout_gravity="center" - android:contentDescription="@string/pip_phone_expand" - android:background="?android:selectableItemBackgroundBorderless" /> - </FrameLayout> + <ImageView + android:id="@+id/dismiss" + android:layout_width="@dimen/pip_action_size" + android:layout_height="@dimen/pip_action_size" + android:layout_gravity="top|end" + android:padding="@dimen/pip_action_padding" + android:contentDescription="@string/pip_phone_close" + android:src="@drawable/ic_close_white" + android:background="?android:selectableItemBackgroundBorderless" /> - <FrameLayout - android:id="@+id/actions_container" - android:layout_width="match_parent" - android:layout_height="@dimen/pip_action_size" - android:layout_gravity="bottom" - android:visibility="invisible"> - <LinearLayout - android:id="@+id/actions_group" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_gravity="center_horizontal" - android:orientation="horizontal" - android:divider="@android:color/transparent" - android:showDividers="middle" /> - </FrameLayout> + <!-- The margins for this container is calculated in the code depending on whether the + actions_container is visible. --> + <FrameLayout + android:id="@+id/expand_container" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <ImageView + android:id="@+id/expand_button" + android:layout_width="60dp" + android:layout_height="60dp" + android:layout_gravity="center" + android:contentDescription="@string/pip_phone_expand" + android:background="?android:selectableItemBackgroundBorderless" /> + </FrameLayout> + + <FrameLayout + android:id="@+id/actions_container" + android:layout_width="match_parent" + android:layout_height="@dimen/pip_action_size" + android:layout_gravity="bottom" + android:visibility="invisible"> + <LinearLayout + android:id="@+id/actions_group" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_gravity="center_horizontal" + android:orientation="horizontal" + android:divider="@android:color/transparent" + android:showDividers="middle" /> + </FrameLayout> + </FrameLayout> </FrameLayout> diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java index 86e2c4956070..2f9c3fc3368a 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java @@ -20,10 +20,12 @@ import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_ACT import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_CONTROLLER_MESSENGER; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MOVEMENT_BOUNDS; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_STACK_BOUNDS; +import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_SHOW_MENU; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityManager; @@ -35,6 +37,8 @@ import android.content.res.Resources; import android.graphics.Color; import android.graphics.PointF; import android.graphics.Rect; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.os.Bundle; import android.os.Handler; @@ -71,13 +75,19 @@ public class PipMenuActivity extends Activity { public static final int MESSAGE_POKE_MENU = 2; public static final int MESSAGE_HIDE_MENU = 3; public static final int MESSAGE_UPDATE_ACTIONS = 4; + public static final int MESSAGE_UPDATE_DISMISS_FRACTION = 5; private static final long INITIAL_DISMISS_DELAY = 2000; private static final long POST_INTERACTION_DISMISS_DELAY = 1500; private static final long MENU_FADE_DURATION = 125; + private static final float MENU_BACKGROUND_ALPHA = 0.3f; + private static final float DISMISS_BACKGROUND_ALPHA = 0.8f; + private boolean mMenuVisible; private final List<RemoteAction> mActions = new ArrayList<>(); + private View mViewRoot; + private Drawable mBackgroundDrawable; private View mMenuContainer; private LinearLayout mActionsGroup; private View mDismissButton; @@ -85,6 +95,14 @@ public class PipMenuActivity extends Activity { private int mBetweenActionPaddingLand; private ObjectAnimator mMenuContainerAnimator; + private ValueAnimator.AnimatorUpdateListener mMenuBgUpdateListener = + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + final float alpha = (float) animation.getAnimatedValue(); + mBackgroundDrawable.setAlpha((int) (MENU_BACKGROUND_ALPHA*alpha*255)); + } + }; private PointF mDownPosition = new PointF(); private PointF mDownDelta = new PointF(); @@ -109,6 +127,10 @@ public class PipMenuActivity extends Activity { Pair<Rect, ParceledListSlice> data = (Pair<Rect, ParceledListSlice>) msg.obj; setActions(data.first, data.second.getList()); break; + case MESSAGE_UPDATE_DISMISS_FRACTION: + float fraction = (float) msg.obj; + updateDismissFraction(fraction); + break; } } }); @@ -130,7 +152,12 @@ public class PipMenuActivity extends Activity { super.onCreate(savedInstanceState); setContentView(R.layout.pip_menu_activity); - mMenuContainer = findViewById(R.id.menu); + mBackgroundDrawable = new ColorDrawable(Color.BLACK); + mBackgroundDrawable.setAlpha(0); + mViewRoot = findViewById(R.id.background); + mViewRoot.setBackground(mBackgroundDrawable); + mMenuContainer = findViewById(R.id.menu_container); + mMenuContainer.setAlpha(0); mMenuContainer.setOnClickListener((v) -> { expandPip(); }); @@ -222,10 +249,10 @@ public class PipMenuActivity extends Activity { private void showMenu(Rect stackBounds, Rect movementBounds) { if (!mMenuVisible) { + updateActionViews(stackBounds); if (mMenuContainerAnimator != null) { mMenuContainerAnimator.cancel(); } - notifyMenuVisibility(true); updateExpandButtonFromBounds(stackBounds, movementBounds); mMenuContainerAnimator = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA, @@ -238,6 +265,7 @@ public class PipMenuActivity extends Activity { repostDelayedFinish(INITIAL_DISMISS_DELAY); } }); + mMenuContainerAnimator.addUpdateListener(mMenuBgUpdateListener); mMenuContainerAnimator.start(); } else { repostDelayedFinish(POST_INTERACTION_DISMISS_DELAY); @@ -269,20 +297,24 @@ public class PipMenuActivity extends Activity { } } }); + mMenuContainerAnimator.addUpdateListener(mMenuBgUpdateListener); mMenuContainerAnimator.start(); } } private void updateFromIntent(Intent intent) { - Rect stackBounds = Rect.unflattenFromString(intent.getStringExtra(EXTRA_STACK_BOUNDS)); - Rect movementBounds = Rect.unflattenFromString(intent.getStringExtra( - EXTRA_MOVEMENT_BOUNDS)); mToControllerMessenger = intent.getParcelableExtra(EXTRA_CONTROLLER_MESSENGER); ParceledListSlice actions = intent.getParcelableExtra(EXTRA_ACTIONS); if (actions != null) { - setActions(stackBounds, actions.getList()); + mActions.clear(); + mActions.addAll(actions.getList()); + } + if (intent.getBooleanExtra(EXTRA_SHOW_MENU, false)) { + Rect stackBounds = Rect.unflattenFromString(intent.getStringExtra(EXTRA_STACK_BOUNDS)); + Rect movementBounds = Rect.unflattenFromString(intent.getStringExtra( + EXTRA_MOVEMENT_BOUNDS)); + showMenu(stackBounds, movementBounds); } - showMenu(stackBounds, movementBounds); } private void updateExpandButtonFromBounds(Rect stackBounds, Rect movementBounds) { @@ -365,6 +397,19 @@ public class PipMenuActivity extends Activity { } } + private void updateDismissFraction(float fraction) { + int alpha; + if (mMenuVisible) { + mMenuContainer.setAlpha(1-fraction); + final float interpolatedAlpha = + MENU_BACKGROUND_ALPHA * (1.0f - fraction) + DISMISS_BACKGROUND_ALPHA * fraction; + alpha = (int) (interpolatedAlpha*255); + } else { + alpha = (int) (fraction*DISMISS_BACKGROUND_ALPHA*255); + } + mBackgroundDrawable.setAlpha(alpha); + } + private void notifyRegisterInputConsumer() { Message m = Message.obtain(); m.what = PipMenuActivityController.MESSAGE_REGISTER_INPUT_CONSUMER; diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java index badf64b90b8f..7dc455bd0d2c 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java @@ -42,7 +42,7 @@ import java.util.ArrayList; import java.util.List; /** - * Manages the PiP menu activity. + * Manages the PiP menu activity which can show menu options or a scrim. * * The current media session provides actions whenever there are no valid actions provided by the * current PiP activity. Otherwise, those actions always take precedence. @@ -55,6 +55,7 @@ public class PipMenuActivityController { public static final String EXTRA_ACTIONS = "actions"; public static final String EXTRA_STACK_BOUNDS = "stack_bounds"; public static final String EXTRA_MOVEMENT_BOUNDS = "movement_bounds"; + public static final String EXTRA_SHOW_MENU = "show_menu"; public static final int MESSAGE_MENU_VISIBILITY_CHANGED = 100; public static final int MESSAGE_EXPAND_PIP = 101; @@ -101,6 +102,7 @@ public class PipMenuActivityController { private ParceledListSlice mMediaActions; private boolean mMenuVisible; + private boolean mStartActivityRequested; private Messenger mToActivityMessenger; private Messenger mMessenger = new Messenger(new Handler() { @Override @@ -135,6 +137,7 @@ public class PipMenuActivityController { } case MESSAGE_UPDATE_ACTIVITY_CALLBACK: { mToActivityMessenger = msg.replyTo; + mStartActivityRequested = false; // Mark the menu as invisible once the activity finishes as well if (mToActivityMessenger == null) { onMenuVisibilityChanged(false, true /* resize */); @@ -179,6 +182,25 @@ public class PipMenuActivityController { } /** + * Updates the appearance of the menu and scrim on top of the PiP while dismissing. + */ + public void setDismissFraction(float fraction) { + if (mToActivityMessenger != null) { + Message m = Message.obtain(); + m.what = PipMenuActivity.MESSAGE_UPDATE_DISMISS_FRACTION; + m.obj = fraction; + try { + mToActivityMessenger.send(m); + } catch (RemoteException e) { + Log.e(TAG, "Could not notify menu to show", e); + } + } else if (!mStartActivityRequested) { + startMenuActivity(null /* stackBounds */, null /* movementBounds */, + false /* showMenu */); + } + } + + /** * Shows the menu activity. */ public void showMenu(Rect stackBounds, Rect movementBounds) { @@ -191,28 +213,8 @@ public class PipMenuActivityController { } catch (RemoteException e) { Log.e(TAG, "Could not notify menu to show", e); } - } else { - // Start the menu activity on the top task of the pinned stack - try { - StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID); - if (pinnedStackInfo != null && pinnedStackInfo.taskIds != null && - pinnedStackInfo.taskIds.length > 0) { - Intent intent = new Intent(mContext, PipMenuActivity.class); - intent.putExtra(EXTRA_CONTROLLER_MESSENGER, mMessenger); - intent.putExtra(EXTRA_ACTIONS, resolveMenuActions()); - intent.putExtra(EXTRA_STACK_BOUNDS, stackBounds.flattenToString()); - intent.putExtra(EXTRA_MOVEMENT_BOUNDS, movementBounds.flattenToString()); - ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0); - options.setLaunchTaskId( - pinnedStackInfo.taskIds[pinnedStackInfo.taskIds.length - 1]); - options.setTaskOverlay(true, true /* canResume */); - mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT); - } else { - Log.e(TAG, "No PIP tasks found"); - } - } catch (RemoteException e) { - Log.e(TAG, "Error showing PIP menu activity", e); - } + } else if (!mStartActivityRequested) { + startMenuActivity(stackBounds, movementBounds, true /* showMenu */); } } @@ -272,6 +274,39 @@ public class PipMenuActivityController { } /** + * Starts the menu activity on the top task of the pinned stack. + */ + private void startMenuActivity(Rect stackBounds, Rect movementBounds, boolean showMenu) { + try { + StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID); + if (pinnedStackInfo != null && pinnedStackInfo.taskIds != null && + pinnedStackInfo.taskIds.length > 0) { + Intent intent = new Intent(mContext, PipMenuActivity.class); + intent.putExtra(EXTRA_CONTROLLER_MESSENGER, mMessenger); + intent.putExtra(EXTRA_ACTIONS, resolveMenuActions()); + if (stackBounds != null) { + intent.putExtra(EXTRA_STACK_BOUNDS, stackBounds.flattenToString()); + } + if (movementBounds != null) { + intent.putExtra(EXTRA_MOVEMENT_BOUNDS, movementBounds.flattenToString()); + } + intent.putExtra(EXTRA_SHOW_MENU, showMenu); + ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0); + options.setLaunchTaskId( + pinnedStackInfo.taskIds[pinnedStackInfo.taskIds.length - 1]); + options.setTaskOverlay(true, true /* canResume */); + mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT); + mStartActivityRequested = true; + } else { + Log.e(TAG, "No PIP tasks found"); + } + } catch (RemoteException e) { + mStartActivityRequested = false; + Log.e(TAG, "Error showing PIP menu activity", e); + } + } + + /** * Updates the PiP menu activity with the best set of actions provided. */ private void updateMenuActions() { diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java index 49d89a2bdd68..c4cf28c9a320 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java @@ -65,9 +65,9 @@ public class PipMotionHelper { private static final int IME_SHIFT_DURATION = 300; // The fraction of the stack width that the user has to drag offscreen to minimize the PiP - private static final float MINIMIZE_OFFSCREEN_FRACTION = 0.2f; - // The fraction of the stack height that the user has to drag offscreen to minimize the PiP - private static final float DISMISS_OFFSCREEN_FRACTION = 0.35f; + private static final float MINIMIZE_OFFSCREEN_FRACTION = 0.3f; + // The fraction of the stack height that the user has to drag offscreen to dismiss the PiP + private static final float DISMISS_OFFSCREEN_FRACTION = 0.15f; private Context mContext; private IActivityManager mActivityManager; @@ -234,12 +234,16 @@ public class PipMotionHelper { /** * Animates the PiP to the minimized state, slightly offscreen. */ - Rect animateToClosestMinimizedState(Rect movementBounds) { + Rect animateToClosestMinimizedState(Rect movementBounds, + AnimatorUpdateListener updateListener) { cancelAnimations(); Rect toBounds = getClosestMinimizedBounds(mBounds, movementBounds); if (!mBounds.equals(toBounds)) { mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, MINIMIZE_STACK_MAX_DURATION, LINEAR_OUT_SLOW_IN, mUpdateBoundsListener); + if (updateListener != null) { + mBoundsAnimator.addUpdateListener(updateListener); + } mBoundsAnimator.start(); } return toBounds; @@ -248,7 +252,8 @@ public class PipMotionHelper { /** * Flings the PiP to the closest snap target. */ - Rect flingToSnapTarget(float velocity, float velocityX, float velocityY, Rect movementBounds) { + Rect flingToSnapTarget(float velocity, float velocityX, float velocityY, Rect movementBounds, + AnimatorUpdateListener listener) { cancelAnimations(); Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds, velocityX, velocityY); @@ -258,6 +263,9 @@ public class PipMotionHelper { mFlingAnimationUtils.apply(mBoundsAnimator, 0, distanceBetweenRectOffsets(mBounds, toBounds), velocity); + if (listener != null) { + mBoundsAnimator.addUpdateListener(listener); + } mBoundsAnimator.start(); } return toBounds; @@ -266,12 +274,15 @@ public class PipMotionHelper { /** * Animates the PiP to the closest snap target. */ - Rect animateToClosestSnapTarget(Rect movementBounds) { + Rect animateToClosestSnapTarget(Rect movementBounds, AnimatorUpdateListener listener) { cancelAnimations(); Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds); if (!mBounds.equals(toBounds)) { mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, SNAP_STACK_DURATION, FAST_OUT_SLOW_IN, mUpdateBoundsListener); + if (listener != null) { + mBoundsAnimator.addUpdateListener(listener); + } mBoundsAnimator.start(); } return toBounds; @@ -316,7 +327,7 @@ public class PipMotionHelper { /** * Animates the dismissal of the PiP off the edge of the screen. */ - Rect animateDragToEdgeDismiss(Rect pipBounds) { + Rect animateDragToEdgeDismiss(Rect pipBounds, AnimatorUpdateListener listener) { cancelAnimations(); Point displaySize = new Point(); mContext.getDisplay().getRealSize(displaySize); @@ -330,6 +341,9 @@ public class PipMotionHelper { dismissPip(); } }); + if (listener != null) { + mBoundsAnimator.addUpdateListener(listener); + } mBoundsAnimator.start(); return toBounds; } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index 80231a954e1a..c52fc3e87b0e 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -16,6 +16,8 @@ package com.android.systemui.pip.phone; +import android.animation.ValueAnimator; +import android.animation.ValueAnimator.AnimatorUpdateListener; import android.app.IActivityManager; import android.content.Context; import android.graphics.Point; @@ -55,7 +57,7 @@ public class PipTouchHandler { // Allow dragging the PIP to a location to close it private static final boolean ENABLE_DISMISS_DRAG_TO_TARGET = false; - private static final boolean ENABLE_DISMISS_DRAG_TO_EDGE = false; + private static final boolean ENABLE_DISMISS_DRAG_TO_EDGE = true; private final Context mContext; private final IActivityManager mActivityManager; @@ -87,6 +89,13 @@ public class PipTouchHandler { } } }; + private ValueAnimator.AnimatorUpdateListener mUpdateScrimListener = + new AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + updateDismissFraction(); + } + }; // Behaviour states private boolean mIsMenuVisible; @@ -124,7 +133,7 @@ public class PipTouchHandler { @Override public void onPipMinimize() { setMinimizedStateInternal(true); - mMotionHelper.animateToClosestMinimizedState(mMovementBounds); + mMotionHelper.animateToClosestMinimizedState(mMovementBounds, null /* updateListener */); } @Override @@ -331,6 +340,22 @@ public class PipTouchHandler { } /** + * Updates the appearance of the menu and scrim on top of the PiP while dismissing. + */ + void updateDismissFraction() { + if (mMenuController != null) { + Rect bounds = mMotionHelper.getBounds(); + final float target = mMovementBounds.bottom + bounds.height(); + float fraction = 0f; + if (bounds.bottom > target) { + final float distance = bounds.bottom - target; + fraction = Math.min(distance / bounds.height(), 1f); + } + mMenuController.setDismissFraction(fraction); + } + } + + /** * Sets the controller to update the system of changes from user interaction. */ void setPinnedStackController(IPinnedStackController controller) { @@ -465,6 +490,9 @@ public class PipTouchHandler { if (ENABLE_DISMISS_DRAG_TO_TARGET) { mDismissViewController.updateDismissTarget(mTmpBounds); } + if (ENABLE_DISMISS_DRAG_TO_EDGE) { + updateDismissFraction(); + } return true; } return false; @@ -502,7 +530,8 @@ public class PipTouchHandler { boolean isFlingToBot = isFlingTowardsEdge(touchState, 4 /* bottom */); if (ENABLE_DISMISS_DRAG_TO_EDGE && (mMotionHelper.shouldDismissPip() || isFlingToBot)) { - mMotionHelper.animateDragToEdgeDismiss(mMotionHelper.getBounds()); + mMotionHelper.animateDragToEdgeDismiss(mMotionHelper.getBounds(), + mUpdateScrimListener); MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED, METRIC_VALUE_DISMISSED_BY_DRAG); @@ -517,7 +546,8 @@ public class PipTouchHandler { // minimize offset adjusted mMenuController.hideMenu(); } else { - mMotionHelper.animateToClosestMinimizedState(mMovementBounds); + mMotionHelper.animateToClosestMinimizedState(mMovementBounds, + mUpdateScrimListener); } return true; } @@ -536,13 +566,14 @@ public class PipTouchHandler { final PointF vel = mTouchState.getVelocity(); final float velocity = PointF.length(vel.x, vel.y); if (velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond()) { - mMotionHelper.flingToSnapTarget(velocity, vel.x, vel.y, mMovementBounds); + mMotionHelper.flingToSnapTarget(velocity, vel.x, vel.y, mMovementBounds, + mUpdateScrimListener); } else { - mMotionHelper.animateToClosestSnapTarget(mMovementBounds); + mMotionHelper.animateToClosestSnapTarget(mMovementBounds, mUpdateScrimListener); } } else if (mIsMinimized) { // This was a tap, so no longer minimized - mMotionHelper.animateToClosestSnapTarget(mMovementBounds); + mMotionHelper.animateToClosestSnapTarget(mMovementBounds, null /* listener */); setMinimizedStateInternal(false); } else if (!mIsMenuVisible) { mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds); diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp index b4630efe80e8..c532efb79345 100644 --- a/rs/jni/android_renderscript_RenderScript.cpp +++ b/rs/jni/android_renderscript_RenderScript.cpp @@ -48,9 +48,6 @@ static constexpr bool kLogApi = false; using namespace android; -template <typename... T> -void UNUSED(T... t) {} - #define PER_ARRAY_TYPE(flag, fnc, readonly, ...) { \ jint len = 0; \ void *ptr = nullptr; \ diff --git a/services/core/java/com/android/server/FontManagerService.java b/services/core/java/com/android/server/FontManagerService.java index 593c3220fdb5..55a945a6fce1 100644 --- a/services/core/java/com/android/server/FontManagerService.java +++ b/services/core/java/com/android/server/FontManagerService.java @@ -71,11 +71,8 @@ public class FontManagerService extends IFontManager.Stub { return null; } - final int size = config.getFamilies().size(); - for (int i = 0; i < size; ++i) { - FontConfig.Family family = config.getFamilies().get(i); - for (int j = 0; j < family.getFonts().size(); ++j) { - FontConfig.Font font = family.getFonts().get(j); + for (FontConfig.Family family : config.getFamilies()) { + for (FontConfig.Font font : family.getFonts()) { File fontFile = new File(font.getFontName()); try { font.setFd(ParcelFileDescriptor.open( diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 75916be3759c..2885e663af3f 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1584,9 +1584,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // If the assistant stack is focused and translucent, then the docked stack is always // visible - if (topStack.isAssistantStack() - && topStack.isStackTranslucent(starting, DOCKED_STACK_ID)) { - return STACK_VISIBLE; + if (topStack.isAssistantStack()) { + return (topStack.isStackTranslucent(starting, DOCKED_STACK_ID)) ? STACK_VISIBLE + : STACK_INVISIBLE; } // Otherwise, the docked stack is always visible, except in the case where the top @@ -3216,7 +3216,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } // Move the home stack to the top if this stack is fullscreen or there is no // other visible stack. - if (mStackSupervisor.moveHomeStackTaskToTop(myReason)) { + if (task.isOverHomeStack() && + mStackSupervisor.moveHomeStackTaskToTop(myReason)) { // Activity focus was already adjusted. Nothing else to do... return; } diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index c0c433e5e1b9..99fe418e66e1 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -2013,10 +2013,6 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta final Configuration parentConfig = getParent().getConfiguration(); final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE; - // TODO: Orientation? - config.orientation = (config.screenWidthDp <= config.screenHeightDp) - ? Configuration.ORIENTATION_PORTRAIT - : Configuration.ORIENTATION_LANDSCAPE; if (mStack != null) { final StackWindowController stackController = mStack.getWindowContainerController(); stackController.adjustConfigurationForBounds(bounds, insetBounds, @@ -2030,6 +2026,10 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta Slog.wtf(TAG, "Expected stack when caclulating override config"); } + config.orientation = (config.screenWidthDp <= config.screenHeightDp) + ? Configuration.ORIENTATION_PORTRAIT + : Configuration.ORIENTATION_LANDSCAPE; + // For calculating screen layout, we need to use the non-decor inset screen area for the // calculation for compatibility reasons, i.e. screen area without system bars that could // never go away in Honeycomb. diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 12890190aefc..4ac1cce91402 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -10565,9 +10565,9 @@ public class PackageManagerService extends IPackageManager.Stub { ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi + " (requirer=" - + (requirer == null ? "null" : requirer.pkg.packageName) + + (requirer != null ? requirer.pkg : "null") + ", scannedPackage=" - + (scannedPackage != null ? scannedPackage.packageName : "null") + + (scannedPackage != null ? scannedPackage : "null") + ")"); try { mInstaller.rmdex(ps.codePathString, diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 75a7385c9bf4..7a36da202aad 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -44,6 +44,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; +import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM; import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE; import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM; @@ -1652,10 +1653,14 @@ public class AppTransition implements Dump { } int getAppStackClipMode() { + // When dismiss keyguard animation occurs, clip before the animation to prevent docked + // app from showing beyond the divider + if (mNextAppTransition == TRANSIT_KEYGUARD_GOING_AWAY + || mNextAppTransition == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER) { + return STACK_CLIP_BEFORE_ANIM; + } return mNextAppTransition == TRANSIT_ACTIVITY_RELAUNCH || mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS - || mNextAppTransition == TRANSIT_KEYGUARD_GOING_AWAY - || mNextAppTransition == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER || mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL ? STACK_CLIP_NONE : STACK_CLIP_AFTER_ANIM; diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java index f1e7b5177e13..45337742998f 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java @@ -415,9 +415,9 @@ public final class ResourceHelper { BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser( parser, context, isFramework); try { - FontConfig config = FontResourcesParser.parse(blockParser, context - .getResources()); - typeface = Typeface.createFromResources(config, context.getAssets(), + FontResourcesParser.FamilyResourceEntry entry = + FontResourcesParser.parse(blockParser, context.getResources()); + typeface = Typeface.createFromResources(entry, context.getAssets(), fontName); } catch (XmlPullParserException | IOException e) { Bridge.getLog().error(null, "Failed to parse file " + fontName, diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 18c124503136..af48d0a2b6ca 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -16,7 +16,11 @@ package android.net.wifi; + +import android.content.pm.ParceledListSlice; + import android.net.wifi.hotspot2.PasspointConfiguration; + import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.ScanSettings; @@ -51,9 +55,9 @@ interface IWifiManager */ oneway void requestActivityInfo(in ResultReceiver result); - List<WifiConfiguration> getConfiguredNetworks(); + ParceledListSlice getConfiguredNetworks(); - List<WifiConfiguration> getPrivilegedConfiguredNetworks(); + ParceledListSlice getPrivilegedConfiguredNetworks(); WifiConfiguration getMatchingWifiConfig(in ScanResult scanResult); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 447cafb11fb1..4f2881b87616 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -21,6 +21,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.bluetooth.BluetoothAdapter; import android.content.Context; +import android.content.pm.ParceledListSlice; import android.net.ConnectivityManager; import android.net.DhcpInfo; import android.net.Network; @@ -46,6 +47,7 @@ import com.android.server.net.NetworkPinner; import java.net.InetAddress; import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.Collections; /** * This class provides the primary API for managing all aspects of Wi-Fi @@ -811,7 +813,12 @@ public class WifiManager { */ public List<WifiConfiguration> getConfiguredNetworks() { try { - return mService.getConfiguredNetworks(); + ParceledListSlice<WifiConfiguration> parceledList = + mService.getConfiguredNetworks(); + if (parceledList == null) { + return Collections.emptyList(); + } + return parceledList.getList(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -821,7 +828,12 @@ public class WifiManager { @SystemApi public List<WifiConfiguration> getPrivilegedConfiguredNetworks() { try { - return mService.getPrivilegedConfiguredNetworks(); + ParceledListSlice<WifiConfiguration> parceledList = + mService.getPrivilegedConfiguredNetworks(); + if (parceledList == null) { + return Collections.emptyList(); + } + return parceledList.getList(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } |