summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Shell/res/values-de/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java52
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java29
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java3
-rw-r--r--libs/hwui/jni/Typeface.cpp102
-rw-r--r--libs/hwui/jni/fonts/Font.cpp54
-rw-r--r--libs/hwui/renderthread/CacheManager.cpp8
-rw-r--r--libs/hwui/renderthread/CacheManager.h3
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp16
-rw-r--r--libs/hwui/renderthread/CanvasContext.h1
18 files changed, 237 insertions, 74 deletions
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 0195f3df83a6..c5e79f87ca50 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -62,9 +62,9 @@
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Bubble schließen"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Unterhaltung nicht als Bubble anzeigen"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Bubbles zum Chatten verwenden"</string>
- <string name="bubbles_user_education_description" msgid="4215862563054175407">"Neue Unterhaltungen erscheinen als unverankerte Symbole, \"Bubbles\" genannt. Wenn du die Bubble öffnen möchtest, tippe sie an. Wenn du sie verschieben möchtest, zieh an ihr."</string>
+ <string name="bubbles_user_education_description" msgid="4215862563054175407">"Neue Unterhaltungen erscheinen als unverankerte Symbole, „Bubbles“ genannt. Wenn du eine Bubble öffnen möchtest, tippe sie an. Wenn du sie verschieben möchtest, zieh an ihr."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Bubble-Einstellungen festlegen"</string>
- <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Tippe auf \"Verwalten\", um Bubbles für diese App zu deaktivieren"</string>
+ <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Tippe auf „Verwalten“, um Bubbles für diese App zu deaktivieren"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Keine kürzlich geschlossenen Bubbles"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Hier werden aktuelle und geschlossene Bubbles angezeigt"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 34f75dab7a1b..c788a03a5b29 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -62,7 +62,7 @@
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ignora bolla"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Non mettere la conversazione nella bolla"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatta utilizzando le bolle"</string>
- <string name="bubbles_user_education_description" msgid="4215862563054175407">"Le nuove conversazioni vengono visualizzate come icone mobili o bolle. Tocca per aprire la bolla. Trascinala per spostarla."</string>
+ <string name="bubbles_user_education_description" msgid="4215862563054175407">"Le nuove conversazioni vengono mostrate come icone mobili o bolle. Tocca per aprire la bolla. Trascinala per spostarla."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Controlla le bolle quando vuoi"</string>
<string name="bubbles_user_education_manage" msgid="3460756219946517198">"Tocca Gestisci per disattivare le bolle dall\'app"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index ef5ed00b4bda..36700bd81717 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -63,7 +63,7 @@
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"会話をバブルで表示しない"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"チャットでバブルを使う"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"新しい会話はフローティング アイコン(バブル)として表示されます。タップするとバブルが開きます。ドラッグしてバブルを移動できます。"</string>
- <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"いつでもバブルを管理"</string>
+ <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"バブルはいつでも管理可能"</string>
<string name="bubbles_user_education_manage" msgid="3460756219946517198">"このアプリからのバブルを OFF にするには、[管理] をタップしてください"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"最近閉じたバブルはありません"</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 8c8a56a773f7..dfd878f63283 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -368,6 +368,13 @@ public class BubbleController {
return;
}
}
+ for (Bubble b : mBubbleData.getOverflowBubbles()) {
+ if (task.taskId == b.getTaskId()) {
+ promoteBubbleFromOverflow(b);
+ mBubbleData.setExpanded(true);
+ return;
+ }
+ }
}
});
@@ -815,7 +822,35 @@ public class BubbleController {
setIsBubble(bubble, true /* isBubble */);
}
- @VisibleForTesting
+ /**
+ * Expands and selects the provided bubble as long as it already exists in the stack or the
+ * overflow.
+ *
+ * This is currently only used when opening a bubble via clicking on a conversation widget.
+ */
+ public void expandStackAndSelectBubble(Bubble b) {
+ if (b == null) {
+ return;
+ }
+ if (mBubbleData.hasBubbleInStackWithKey(b.getKey())) {
+ // already in the stack
+ mBubbleData.setSelectedBubble(b);
+ mBubbleData.setExpanded(true);
+ } else if (mBubbleData.hasOverflowBubbleWithKey(b.getKey())) {
+ // promote it out of the overflow
+ promoteBubbleFromOverflow(b);
+ }
+ }
+
+ /**
+ * Expands and selects a bubble based on the provided {@link BubbleEntry}. If no bubble
+ * exists for this entry, and it is able to bubble, a new bubble will be created.
+ *
+ * This is the method to use when opening a bubble via a notification or in a state where
+ * the device might not be unlocked.
+ *
+ * @param entry the entry to use for the bubble.
+ */
public void expandStackAndSelectBubble(BubbleEntry entry) {
if (mIsStatusBarShade) {
mNotifEntryToExpandOnShadeUnlock = null;
@@ -1383,6 +1418,21 @@ public class BubbleController {
}
@Override
+ public void expandStackAndSelectBubble(Bubble bubble) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.expandStackAndSelectBubble(bubble);
+ });
+ }
+
+ @Override
+ @Nullable
+ public Bubble getBubbleWithShortcutId(String shortcutId) {
+ return mMainExecutor.executeBlockingForResult(() -> {
+ return BubbleController.this.mBubbleData.getAnyBubbleWithShortcutId(shortcutId);
+ }, Bubble.class);
+ }
+
+ @Override
public void onTaskbarChanged(Bundle b) {
mMainExecutor.execute(() -> {
BubbleController.this.onTaskbarChanged(b);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 69a741c674db..6f5cfd114688 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -26,6 +26,7 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.LocusId;
import android.content.pm.ShortcutInfo;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
@@ -874,6 +875,34 @@ public class BubbleData {
return b;
}
+ /** @return any bubble (in the stack or the overflow) that matches the provided shortcutId. */
+ @Nullable
+ Bubble getAnyBubbleWithShortcutId(String shortcutId) {
+ if (TextUtils.isEmpty(shortcutId)) {
+ return null;
+ }
+ for (int i = 0; i < mBubbles.size(); i++) {
+ Bubble bubble = mBubbles.get(i);
+ String bubbleShortcutId = bubble.getShortcutInfo() != null
+ ? bubble.getShortcutInfo().getId()
+ : bubble.getMetadataShortcutId();
+ if (shortcutId.equals(bubbleShortcutId)) {
+ return bubble;
+ }
+ }
+
+ for (int i = 0; i < mOverflowBubbles.size(); i++) {
+ Bubble bubble = mOverflowBubbles.get(i);
+ String bubbleShortcutId = bubble.getShortcutInfo() != null
+ ? bubble.getShortcutInfo().getId()
+ : bubble.getMetadataShortcutId();
+ if (shortcutId.equals(bubbleShortcutId)) {
+ return bubble;
+ }
+ }
+ return null;
+ }
+
@VisibleForTesting(visibility = PRIVATE)
@Nullable
public Bubble getBubbleInStackWithKey(String key) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 16b8150467fd..c71f123459ec 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -50,7 +50,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
-import android.view.WindowInsets;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.widget.FrameLayout;
@@ -1018,7 +1017,10 @@ public class BubbleStackView extends FrameLayout
removeView(mDismissView);
}
mDismissView = new DismissView(getContext());
+ int elevation = getResources().getDimensionPixelSize(R.dimen.bubble_elevation);
+
addView(mDismissView);
+ mDismissView.setElevation(elevation);
final ContentResolver contentResolver = getContext().getContentResolver();
final int dismissRadius = Settings.Secure.getInt(
@@ -1028,6 +1030,8 @@ public class BubbleStackView extends FrameLayout
// MagnetizedObjects.
mMagneticTarget = new MagnetizedObject.MagneticTarget(
mDismissView.getCircle(), dismissRadius);
+
+ mBubbleContainer.bringToFront();
}
// TODO: Create ManageMenuView and move setup / animations there
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index a93ce01dfc7b..c73b5eebc5c2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -118,6 +118,19 @@ public interface Bubbles {
*/
void expandStackAndSelectBubble(BubbleEntry entry);
+ /**
+ * Request the stack expand if needed, then select the specified Bubble as current.
+ *
+ * @param bubble the bubble to be selected
+ */
+ void expandStackAndSelectBubble(Bubble bubble);
+
+ /**
+ * @return a bubble that matches the provided shortcutId, if one exists.
+ */
+ @Nullable
+ Bubble getBubbleWithShortcutId(String shortcutId);
+
/** Called for any taskbar changes. */
void onTaskbarChanged(Bundle b);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
index ee2202a48bf2..261ff2f8de83 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
@@ -550,12 +550,14 @@ public class LegacySplitScreenController implements DisplayController.OnDisplays
update(mDisplayController.getDisplayContext(
mContext.getDisplayId()).getResources().getConfiguration());
// Set resizable directly here because applyEnterSplit already resizes home stack.
- mHomeStackResizable = mWindowManagerProxy.applyEnterSplit(mSplits, mSplitLayout);
+ mHomeStackResizable = mWindowManagerProxy.applyEnterSplit(mSplits,
+ mRotateSplitLayout != null ? mRotateSplitLayout : mSplitLayout);
}
public void prepareEnterSplitTransition(WindowContainerTransaction outWct) {
// Set resizable directly here because buildEnterSplit already resizes home stack.
- mHomeStackResizable = mWindowManagerProxy.buildEnterSplit(outWct, mSplits, mSplitLayout);
+ mHomeStackResizable = mWindowManagerProxy.buildEnterSplit(outWct, mSplits,
+ mRotateSplitLayout != null ? mRotateSplitLayout : mSplitLayout);
}
public void finishEnterSplitTransition(boolean minimized) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
index 49266ce1bb62..c275d50a5d56 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
@@ -71,6 +71,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
"persist.debug.one_handed_offset_percentage";
private static final String ONE_HANDED_MODE_GESTURAL_OVERLAY =
"com.android.internal.systemui.onehanded.gestural";
+ private static final int OVERLAY_ENABLED_DELAY_MS = 250;
static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
@@ -493,9 +494,11 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
setOneHandedEnabled(enabled);
// Also checks swipe to notification settings since they all need gesture overlay.
- setEnabledGesturalOverlay(
+ // Enabled overlay package may affect the current animation(e.g:Settings switch),
+ // so we delay 250ms to enabled overlay after switch animation finish
+ mMainExecutor.executeDelayed(() -> setEnabledGesturalOverlay(
enabled || mOneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
- mContext.getContentResolver(), mUserId));
+ mContext.getContentResolver(), mUserId)), OVERLAY_ENABLED_DELAY_MS);
}
@VisibleForTesting
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index 02451c30d4ef..f6b5889dda28 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -202,6 +202,7 @@ public class PhonePipMenuController implements PipMenuController {
mSystemWindows.updateViewLayout(mPipMenuView,
getPipMenuLayoutParams(MENU_WINDOW_TITLE, destinationBounds.width(),
destinationBounds.height()));
+ updateMenuLayout(destinationBounds);
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
index 604ebc08f42e..c42750d62dd4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -684,7 +684,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
// Intentionally resize here even if the current bounds match the destination bounds.
// This is so all the proper callbacks are performed.
mPipTaskOrganizer.scheduleAnimateResizePip(toBounds, duration,
- TRANSITION_DIRECTION_EXPAND_OR_UNEXPAND, mUpdateBoundsCallback);
+ TRANSITION_DIRECTION_EXPAND_OR_UNEXPAND, null /* updateBoundsCallback */);
setAnimatingToBounds(toBounds);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
index 32553f97c020..841edef9172f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -536,8 +536,9 @@ public class PipResizeGestureHandler {
mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds,
PipAnimationController.TRANSITION_DIRECTION_USER_RESIZE, callback);
}
+ final float magnetRadiusPercent = (float) mLastResizeBounds.width() / mMinSize.x / 2.f;
mPipDismissTargetHandler
- .setMagneticFieldRadiusPercent((float) mLastResizeBounds.width() / mMinSize.x);
+ .setMagneticFieldRadiusPercent(magnetRadiusPercent);
mPipUiEventLogger.log(
PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE);
} else {
diff --git a/libs/hwui/jni/Typeface.cpp b/libs/hwui/jni/Typeface.cpp
index ee7b26058952..d86d9ee56f4c 100644
--- a/libs/hwui/jni/Typeface.cpp
+++ b/libs/hwui/jni/Typeface.cpp
@@ -204,10 +204,9 @@ static sk_sp<SkData> makeSkDataCached(const std::string& path, bool hasVerity) {
return entry;
}
-static std::function<std::shared_ptr<minikin::MinikinFont>()> readMinikinFontSkia(
- minikin::BufferReader* reader) {
- const void* buffer = reader->data();
- size_t pos = reader->pos();
+static std::shared_ptr<minikin::MinikinFont> loadMinikinFontSkia(minikin::BufferReader);
+
+static minikin::Font::TypefaceLoader* readMinikinFontSkia(minikin::BufferReader* reader) {
// Advance reader's position.
reader->skipString(); // fontPath
reader->skip<int>(); // fontIndex
@@ -217,60 +216,63 @@ static std::function<std::shared_ptr<minikin::MinikinFont>()> readMinikinFontSki
reader->skip<uint32_t>(); // expectedFontRevision
reader->skipString(); // expectedPostScriptName
}
- return [buffer, pos]() -> std::shared_ptr<minikin::MinikinFont> {
- minikin::BufferReader fontReader(buffer, pos);
- std::string_view fontPath = fontReader.readString();
- std::string path(fontPath.data(), fontPath.size());
- ATRACE_FORMAT("Loading font %s", path.c_str());
- int fontIndex = fontReader.read<int>();
- const minikin::FontVariation* axesPtr;
- uint32_t axesCount;
- std::tie(axesPtr, axesCount) = fontReader.readArray<minikin::FontVariation>();
- bool hasVerity = static_cast<bool>(fontReader.read<int8_t>());
- uint32_t expectedFontRevision;
- std::string_view expectedPostScriptName;
- if (hasVerity) {
- expectedFontRevision = fontReader.read<uint32_t>();
- expectedPostScriptName = fontReader.readString();
- }
- sk_sp<SkData> data = makeSkDataCached(path, hasVerity);
- if (data.get() == nullptr) {
- // This may happen if:
- // 1. When the process failed to open the file (e.g. invalid path or permission).
- // 2. When the process failed to map the file (e.g. hitting max_map_count limit).
- ALOGE("Failed to make SkData from file name: %s", path.c_str());
+ return &loadMinikinFontSkia;
+}
+
+static std::shared_ptr<minikin::MinikinFont> loadMinikinFontSkia(minikin::BufferReader reader) {
+ std::string_view fontPath = reader.readString();
+ std::string path(fontPath.data(), fontPath.size());
+ ATRACE_FORMAT("Loading font %s", path.c_str());
+ int fontIndex = reader.read<int>();
+ const minikin::FontVariation* axesPtr;
+ uint32_t axesCount;
+ std::tie(axesPtr, axesCount) = reader.readArray<minikin::FontVariation>();
+ bool hasVerity = static_cast<bool>(reader.read<int8_t>());
+ uint32_t expectedFontRevision;
+ std::string_view expectedPostScriptName;
+ if (hasVerity) {
+ expectedFontRevision = reader.read<uint32_t>();
+ expectedPostScriptName = reader.readString();
+ }
+ sk_sp<SkData> data = makeSkDataCached(path, hasVerity);
+ if (data.get() == nullptr) {
+ // This may happen if:
+ // 1. When the process failed to open the file (e.g. invalid path or permission).
+ // 2. When the process failed to map the file (e.g. hitting max_map_count limit).
+ ALOGE("Failed to make SkData from file name: %s", path.c_str());
+ return nullptr;
+ }
+ const void* fontPtr = data->data();
+ size_t fontSize = data->size();
+ if (hasVerity) {
+ // Verify font metadata if verity is enabled.
+ minikin::FontFileParser parser(fontPtr, fontSize, fontIndex);
+ std::optional<uint32_t> revision = parser.getFontRevision();
+ if (!revision.has_value() || revision.value() != expectedFontRevision) {
+ LOG_ALWAYS_FATAL("Wrong font revision: %s", path.c_str());
return nullptr;
}
- const void* fontPtr = data->data();
- size_t fontSize = data->size();
- if (hasVerity) {
- // Verify font metadata if verity is enabled.
- minikin::FontFileParser parser(fontPtr, fontSize, fontIndex);
- std::optional<uint32_t> revision = parser.getFontRevision();
- if (!revision.has_value() || revision.value() != expectedFontRevision) {
- LOG_ALWAYS_FATAL("Wrong font revision: %s", path.c_str());
- return nullptr;
- }
- std::optional<std::string> psName = parser.getPostScriptName();
- if (!psName.has_value() || psName.value() != expectedPostScriptName) {
- LOG_ALWAYS_FATAL("Wrong PostScript name: %s", path.c_str());
- return nullptr;
- }
- }
- std::vector<minikin::FontVariation> axes(axesPtr, axesPtr + axesCount);
- std::shared_ptr<minikin::MinikinFont> minikinFont =
- fonts::createMinikinFontSkia(std::move(data), fontPath, fontPtr, fontSize,
- fontIndex, axes);
- if (minikinFont == nullptr) {
- ALOGE("Failed to create MinikinFontSkia: %s", path.c_str());
+ std::optional<std::string> psName = parser.getPostScriptName();
+ if (!psName.has_value() || psName.value() != expectedPostScriptName) {
+ LOG_ALWAYS_FATAL("Wrong PostScript name: %s", path.c_str());
return nullptr;
}
- return minikinFont;
- };
+ }
+ std::vector<minikin::FontVariation> axes(axesPtr, axesPtr + axesCount);
+ std::shared_ptr<minikin::MinikinFont> minikinFont = fonts::createMinikinFontSkia(
+ std::move(data), fontPath, fontPtr, fontSize, fontIndex, axes);
+ if (minikinFont == nullptr) {
+ ALOGE("Failed to create MinikinFontSkia: %s", path.c_str());
+ return nullptr;
+ }
+ return minikinFont;
}
static void writeMinikinFontSkia(minikin::BufferWriter* writer,
const minikin::MinikinFont* typeface) {
+ // When you change the format of font metadata, please update code to parse
+ // typefaceMetadataReader() in
+ // frameworks/base/libs/hwui/jni/fonts/Font.cpp too.
const std::string& path = typeface->GetFontPath();
writer->writeString(path);
writer->write<int>(typeface->GetFontIndex());
diff --git a/libs/hwui/jni/fonts/Font.cpp b/libs/hwui/jni/fonts/Font.cpp
index bd3b7c93466c..09be630dc741 100644
--- a/libs/hwui/jni/fonts/Font.cpp
+++ b/libs/hwui/jni/fonts/Font.cpp
@@ -192,7 +192,7 @@ static jfloat Font_getFontMetrics(JNIEnv* env, jobject, jlong fontHandle, jlong
// Critical Native
static jlong Font_getMinikinFontPtr(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
- return reinterpret_cast<jlong>(font->font->typeface().get());
+ return reinterpret_cast<jlong>(font->font.get());
}
// Critical Native
@@ -224,12 +224,21 @@ static jlong Font_getReleaseNativeFontFunc(CRITICAL_JNI_PARAMS) {
// Fast Native
static jstring Font_getFontPath(JNIEnv* env, jobject, jlong fontPtr) {
FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
- const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
- const std::string& path = minikinFont->GetFontPath();
- if (path.empty()) {
- return nullptr;
+ minikin::BufferReader reader = font->font->typefaceMetadataReader();
+ if (reader.data() != nullptr) {
+ std::string path = std::string(reader.readString());
+ if (path.empty()) {
+ return nullptr;
+ }
+ return env->NewStringUTF(path.c_str());
+ } else {
+ const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
+ const std::string& path = minikinFont->GetFontPath();
+ if (path.empty()) {
+ return nullptr;
+ }
+ return env->NewStringUTF(path.c_str());
}
- return env->NewStringUTF(path.c_str());
}
// Fast Native
@@ -257,22 +266,43 @@ static jint Font_getPackedStyle(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
// Critical Native
static jint Font_getIndex(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
- const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
- return minikinFont->GetFontIndex();
+ minikin::BufferReader reader = font->font->typefaceMetadataReader();
+ if (reader.data() != nullptr) {
+ reader.skipString(); // fontPath
+ return reader.read<int>();
+ } else {
+ const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
+ return minikinFont->GetFontIndex();
+ }
}
// Critical Native
static jint Font_getAxisCount(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
- const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
- return minikinFont->GetAxes().size();
+ minikin::BufferReader reader = font->font->typefaceMetadataReader();
+ if (reader.data() != nullptr) {
+ reader.skipString(); // fontPath
+ reader.skip<int>(); // fontIndex
+ return reader.readArray<minikin::FontVariation>().second;
+ } else {
+ const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
+ return minikinFont->GetAxes().size();
+ }
}
// Critical Native
static jlong Font_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr, jint index) {
FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
- const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
- minikin::FontVariation var = minikinFont->GetAxes().at(index);
+ minikin::BufferReader reader = font->font->typefaceMetadataReader();
+ minikin::FontVariation var;
+ if (reader.data() != nullptr) {
+ reader.skipString(); // fontPath
+ reader.skip<int>(); // fontIndex
+ var = reader.readArray<minikin::FontVariation>().first[index];
+ } else {
+ const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
+ var = minikinFont->GetAxes().at(index);
+ }
uint32_t floatBinary = *reinterpret_cast<const uint32_t*>(&var.value);
return (static_cast<uint64_t>(var.axisTag) << 32) | static_cast<uint64_t>(floatBinary);
}
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index 46e806081c0c..ded2b06fb3cf 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -210,6 +210,14 @@ void CacheManager::onFrameCompleted() {
}
}
+void CacheManager::performDeferredCleanup(nsecs_t cleanupOlderThanMillis) {
+ if (mGrContext) {
+ mGrContext->performDeferredCleanup(
+ std::chrono::milliseconds(cleanupOlderThanMillis),
+ /* scratchResourcesOnly */true);
+ }
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h
index 713ea990ff23..af82672c6f23 100644
--- a/libs/hwui/renderthread/CacheManager.h
+++ b/libs/hwui/renderthread/CacheManager.h
@@ -23,6 +23,7 @@
#include <SkSurface.h>
#include <utils/String8.h>
#include <vector>
+#include "utils/TimeUtils.h"
namespace android {
@@ -53,6 +54,8 @@ public:
size_t getBackgroundCacheSize() const { return mBackgroundResourceBytes; }
void onFrameCompleted();
+ void performDeferredCleanup(nsecs_t cleanupOlderThanMillis);
+
private:
friend class RenderThread;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index a0d93e928876..8bfc2c14ad7c 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -461,6 +461,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy
}
void CanvasContext::stopDrawing() {
+ cleanupResources();
mRenderThread.removeFrameCallback(this);
mAnimationContext->pauseAnimators();
mGenerationID++;
@@ -619,10 +620,25 @@ nsecs_t CanvasContext::draw() {
}
}
+ cleanupResources();
mRenderThread.cacheManager().onFrameCompleted();
return mCurrentFrameInfo->get(FrameInfoIndex::DequeueBufferDuration);
}
+void CanvasContext::cleanupResources() {
+ auto& tracker = mJankTracker.frames();
+ auto size = tracker.size();
+ auto capacity = tracker.capacity();
+ if (size == capacity) {
+ nsecs_t nowNanos = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t frameCompleteNanos =
+ tracker[0].get(FrameInfoIndex::FrameCompleted);
+ nsecs_t frameDiffNanos = nowNanos - frameCompleteNanos;
+ nsecs_t cleanupMillis = ns2ms(std::max(frameDiffNanos, 10_s));
+ mRenderThread.cacheManager().performDeferredCleanup(cleanupMillis);
+ }
+}
+
void CanvasContext::reportMetricsWithPresentTime() {
if (mFrameMetricsReporter == nullptr) {
return;
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 6f90e81e51b0..4bdc2514db8c 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -312,6 +312,7 @@ private:
bool mExpectSurfaceStats = false;
std::function<void(int64_t, int64_t, int64_t)> mASurfaceTransactionCallback;
+ void cleanupResources();
};
} /* namespace renderthread */