Add error logging and better crash safety for app pairs
This causes app pairs to log an error message if creation or icon inflation is attempted with contents != 2. App pairs with wrong numbers of members should not be created anymore. Fixes: 317283244 Fixes: 322892793 Test: Manual Flag: ACONFIG com.android.wm.shell.enable_app_pairs TEAMFOOD Change-Id: I5e454042719bb67187f900c546380bb44cfc34ac
This commit is contained in:
@@ -27,6 +27,7 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.isPersisten
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
@@ -58,6 +59,8 @@ import java.util.Arrays;
|
||||
* ratio.
|
||||
*/
|
||||
public class AppPairsController {
|
||||
private static final String TAG = "AppPairsController";
|
||||
|
||||
// Used for encoding and decoding the "rank" attribute
|
||||
private static final int BITMASK_SIZE = 16;
|
||||
private static final int BITMASK_FOR_SNAP_POSITION = (1 << BITMASK_SIZE) - 1;
|
||||
@@ -89,13 +92,23 @@ public class AppPairsController {
|
||||
|
||||
@PersistentSnapPosition int snapPosition = gtv.getSnapPosition();
|
||||
if (!isPersistentSnapPosition(snapPosition)) {
|
||||
throw new RuntimeException("tried to save an app pair with illegal snapPosition");
|
||||
// if we received an illegal snap position, log an error and do not create the app pair.
|
||||
Log.wtf(TAG, "tried to save an app pair with illegal snapPosition " + snapPosition);
|
||||
return;
|
||||
}
|
||||
|
||||
app1.rank = encodeRank(SPLIT_POSITION_TOP_OR_LEFT, snapPosition);
|
||||
app2.rank = encodeRank(SPLIT_POSITION_BOTTOM_OR_RIGHT, snapPosition);
|
||||
FolderInfo newAppPair = FolderInfo.createAppPair(app1, app2);
|
||||
|
||||
if (newAppPair.contents.size() != 2) {
|
||||
// if app pair doesn't have exactly 2 members, log an error and do not create the app
|
||||
// pair.
|
||||
Log.wtf(TAG,
|
||||
"tried to save an app pair with " + newAppPair.contents.size() + " members");
|
||||
return;
|
||||
}
|
||||
|
||||
IconCache iconCache = LauncherAppState.getInstance(mContext).getIconCache();
|
||||
MODEL_EXECUTOR.execute(() -> {
|
||||
newAppPair.contents.forEach(member -> {
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.launcher3.apppairs;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -45,6 +46,8 @@ import java.util.Comparator;
|
||||
* member apps are set into these rectangles.
|
||||
*/
|
||||
public class AppPairIcon extends FrameLayout implements DraggableView, Reorderable {
|
||||
private static final String TAG = "AppPairIcon";
|
||||
|
||||
// A view that holds the app pair icon graphic.
|
||||
private AppPairIconGraphic mIconGraphic;
|
||||
// A view that holds the app pair's title.
|
||||
@@ -96,8 +99,7 @@ public class AppPairIcon extends FrameLayout implements DraggableView, Reorderab
|
||||
icon.mAppPairName.setText(appPairInfo.title);
|
||||
|
||||
// Set up accessibility
|
||||
icon.setContentDescription(icon.getAccessibilityTitle(
|
||||
appPairInfo.contents.get(0).title, appPairInfo.contents.get(1).title));
|
||||
icon.setContentDescription(icon.getAccessibilityTitle(appPairInfo));
|
||||
icon.setAccessibilityDelegate(activity.getAccessibilityDelegate());
|
||||
|
||||
return icon;
|
||||
@@ -106,7 +108,14 @@ public class AppPairIcon extends FrameLayout implements DraggableView, Reorderab
|
||||
/**
|
||||
* Returns a formatted accessibility title for app pairs.
|
||||
*/
|
||||
public String getAccessibilityTitle(CharSequence app1, CharSequence app2) {
|
||||
public String getAccessibilityTitle(FolderInfo appPairInfo) {
|
||||
if (appPairInfo.contents.size() != 2) {
|
||||
Log.wtf(TAG, "AppPair contents not 2, size: " + appPairInfo.contents.size());
|
||||
return "";
|
||||
}
|
||||
|
||||
CharSequence app1 = appPairInfo.contents.get(0).title;
|
||||
CharSequence app2 = appPairInfo.contents.get(1).title;
|
||||
return getContext().getString(R.string.app_pair_name_format, app1, app2);
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: Attr
|
||||
private fun applyIcons(contents: ArrayList<WorkspaceItemInfo>) {
|
||||
// App pair should always contain 2 members; if not 2, return to avoid a crash loop
|
||||
if (contents.size != 2) {
|
||||
Log.w(TAG, "AppPair contents not 2, size: " + contents.size, Throwable())
|
||||
Log.wtf(TAG, "AppPair contents not 2, size: " + contents.size, Throwable())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -112,7 +112,6 @@ class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: Attr
|
||||
appIcon2?.setBounds(0, 0, memberIconSize.toInt(), memberIconSize.toInt())
|
||||
}
|
||||
|
||||
|
||||
/** Gets this icon graphic's bounds, with respect to the parent icon's coordinate system. */
|
||||
fun getIconBounds(outBounds: Rect) {
|
||||
outBounds.set(0, 0, backgroundSize.toInt(), backgroundSize.toInt())
|
||||
|
||||
Reference in New Issue
Block a user