From 86ae0a75c03bd5db8c3791c2daf7b17cbfd2408c Mon Sep 17 00:00:00 2001 From: John Hoford Date: Mon, 10 Jan 2022 13:34:29 -0800 Subject: [PATCH] add json dump getSceneString() to ConstraintLayout (#482) --- .../widget/ConstraintLayout.java | 45 +++++++++ .../core/widgets/ConstraintWidget.java | 95 ++++++++++++++++++- .../widgets/ConstraintWidgetContainer.java | 17 ++++ .../app/src/main/AndroidManifest.xml | 1 + .../support/constraint/app/CheckDumpJson.java | 62 ++++++++++++ .../constraint/app/VerificationActivity.java | 6 +- .../app/src/main/res/layout/basic_cl_001.xml | 17 ++++ .../app/src/main/res/layout/basic_cl_002.xml | 86 +++++++++++++++++ 8 files changed, 326 insertions(+), 3 deletions(-) create mode 100644 projects/MotionLayoutVerification/app/src/main/java/android/support/constraint/app/CheckDumpJson.java create mode 100644 projects/MotionLayoutVerification/app/src/main/res/layout/basic_cl_001.xml create mode 100644 projects/MotionLayoutVerification/app/src/main/res/layout/basic_cl_002.xml diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java index 876aec6ea..c6e4de20f 100644 --- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java +++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java @@ -3631,4 +3631,49 @@ private void markHierarchyDirty() { public boolean shouldDelayChildPressedState() { return false; } + + /** + * Returns a JSON5 string useful for debugging the constraints actually applied. + * In situations where a complex set of code dynamically constructs constraints + * it is useful to be able to query the layout for what are the constraints. + * @return json5 string representing the constraint in effect now. + */ + public String getSceneString() { + StringBuilder ret = new StringBuilder(); + + if (mLayoutWidget.stringId == null) { + int id = this.getId(); + if (id != -1) { + String str = getContext().getResources().getResourceEntryName(id); + mLayoutWidget.stringId = str; + } else { + mLayoutWidget.stringId = "parent"; + } + } + if (mLayoutWidget.getDebugName() == null) { + mLayoutWidget.setDebugName(mLayoutWidget.stringId); + Log.v(TAG, " setDebugName " + mLayoutWidget.getDebugName()); + } + + ArrayList children = mLayoutWidget.getChildren(); + for (ConstraintWidget child : children) { + View v = (View) child.getCompanionWidget(); + if (v != null) { + if (child.stringId == null) { + int id = v.getId(); + if (id != -1) { + String str = getContext().getResources().getResourceEntryName(id); + child.stringId = str; + } + } + if (child.getDebugName() == null) { + child.setDebugName(child.stringId); + Log.v(TAG, " setDebugName " + child.getDebugName()); + } + + } + } + mLayoutWidget.getSceneString(ret); + return ret.toString(); + } } diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/ConstraintWidget.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/ConstraintWidget.java index 4b15eb42d..685f15c43 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/ConstraintWidget.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/ConstraintWidget.java @@ -615,7 +615,17 @@ private void serializeAttribute(StringBuilder ret, String type, float value, flo } ret.append(type); ret.append(" : "); - ret.append(def); + ret.append(value); + ret.append(",\n"); + } + + private void serializeAttribute(StringBuilder ret, String type, int value, int def){ + if (value == def) { + return; + } + ret.append(type); + ret.append(" : "); + ret.append(value); ret.append(",\n"); } @@ -3553,4 +3563,87 @@ public void addChildrenToSolverByDependency(ConstraintWidgetContainer container, // horizontal } + public void getSceneString(StringBuilder ret ) { + + ret.append(" "+stringId+":{\n"); + ret.append(" actualWidth:" + mWidth); + ret.append("\n"); + ret.append(" actualHeight:" + mHeight); + ret.append("\n"); + ret.append(" actualLeft:" + mX); + ret.append("\n"); + ret.append(" actualTop:" + mY); + ret.append("\n"); + getSceneString(ret,"left", mLeft); + getSceneString(ret,"top", mTop ); + getSceneString(ret,"right", mRight); + getSceneString(ret,"bottom", mBottom); + getSceneString(ret,"baseline", mBaseline); + getSceneString(ret,"centerX", mCenterX); + getSceneString(ret,"centerY", mCenterY); + getSceneString(ret," width", + mWidth, + mMinWidth, + mMaxDimension[HORIZONTAL], + mWidthOverride, + mMatchConstraintMinWidth, + mMatchConstraintDefaultWidth, + mMatchConstraintPercentWidth, + mWeight[DIMENSION_HORIZONTAL] + ); + + getSceneString(ret," height", + mHeight, + mMinHeight, + mMaxDimension[VERTICAL], + mHeightOverride, + mMatchConstraintMinHeight, + mMatchConstraintDefaultHeight, + mMatchConstraintPercentHeight, + mWeight[DIMENSION_VERTICAL]); + serializeDimensionRatio(ret," dimensionRatio",mDimensionRatio, mDimensionRatioSide); + serializeAttribute(ret," horizontalBias",mHorizontalBiasPercent,DEFAULT_BIAS ); + serializeAttribute(ret," verticalBias",mVerticalBiasPercent,DEFAULT_BIAS ); + serializeAttribute(ret," horizontalChainStyle",mHorizontalChainStyle,CHAIN_SPREAD ); + serializeAttribute(ret," verticalChainStyle",mVerticalChainStyle,CHAIN_SPREAD ); + + ret.append(" }"); + + } + + private void getSceneString(StringBuilder ret, String type, int size, + int min, int max, int override, + int matchConstraintMin, int matchConstraintDefault, + float MatchConstraintPercent, + float weight){ + ret.append(type); + ret.append(" : {\n"); + serializeAttribute(ret," size",size,0); + serializeAttribute(ret," min",min,0); + serializeAttribute(ret," max",max, Integer.MAX_VALUE); + serializeAttribute(ret," matchMin",matchConstraintMin, 0); + serializeAttribute(ret," matchDef",matchConstraintDefault, MATCH_CONSTRAINT_SPREAD); + serializeAttribute(ret," matchPercent",MatchConstraintPercent, 1); + ret.append(" },\n"); + } + private void getSceneString(StringBuilder ret, String side, ConstraintAnchor a) { + if (a.mTarget == null) { + return; + } + ret.append(" "); + ret.append(side); + ret.append(" : [ '"); + ret.append(a.mTarget); + ret.append("'"); + if (a.mGoneMargin != Integer.MIN_VALUE || a.mMargin != 0) { + ret.append(","); + ret.append(a.mMargin); + if (a.mGoneMargin != Integer.MIN_VALUE) { + ret.append(","); + ret.append(a.mGoneMargin); + ret.append(","); + } + } + ret.append(" ] ,\n"); + } } diff --git a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/ConstraintWidgetContainer.java b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/ConstraintWidgetContainer.java index 70115be95..55a550f13 100644 --- a/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/ConstraintWidgetContainer.java +++ b/constraintlayout/core/src/main/java/androidx/constraintlayout/core/widgets/ConstraintWidgetContainer.java @@ -1101,4 +1101,21 @@ private void addVerticalChain(ConstraintWidget widget) { public void setPass(int pass) { this.pass = pass; } + + public void getSceneString(StringBuilder ret ) { + + ret.append(stringId+":{\n"); + ret.append(" actualWidth:" + mWidth); + ret.append("\n"); + ret.append(" actualHeight:" + mHeight); + ret.append("\n"); + + ArrayList children = getChildren(); + for (ConstraintWidget child : children) { + child.getSceneString(ret); + ret.append(",\n"); + } + ret.append("}"); + + } } diff --git a/projects/MotionLayoutVerification/app/src/main/AndroidManifest.xml b/projects/MotionLayoutVerification/app/src/main/AndroidManifest.xml index 1b8d4b634..1c9cb6d7a 100644 --- a/projects/MotionLayoutVerification/app/src/main/AndroidManifest.xml +++ b/projects/MotionLayoutVerification/app/src/main/AndroidManifest.xml @@ -43,6 +43,7 @@ + diff --git a/projects/MotionLayoutVerification/app/src/main/java/android/support/constraint/app/CheckDumpJson.java b/projects/MotionLayoutVerification/app/src/main/java/android/support/constraint/app/CheckDumpJson.java new file mode 100644 index 000000000..704b7402c --- /dev/null +++ b/projects/MotionLayoutVerification/app/src/main/java/android/support/constraint/app/CheckDumpJson.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.support.constraint.app; + +import android.content.Context; +import android.os.Bundle; + +import android.util.Log; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.constraintlayout.motion.widget.Debug; +import androidx.constraintlayout.widget.ConstraintLayout; + +// used with verification_057.xml +public class CheckDumpJson extends AppCompatActivity { + private static final String TAG = "CheckDumpJson"; + String layout_name; + ConstraintLayout mLayout; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + int id = R.layout.basic_cl_001; + Bundle extra = getIntent().getExtras(); + if (extra != null) { + String prelayout = extra.getString(Utils.KEY); + setTitle(layout_name = prelayout); + Context ctx = getApplicationContext(); + id = ctx.getResources().getIdentifier(prelayout, "layout", ctx.getPackageName()); + + } + setContentView(id); + mLayout = Utils.findConstraintLayout(this); + + + } + + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + mLayout.postDelayed(()-> dumpJson(), 2000); + } + + private void dumpJson() { + Log.v(TAG, Debug.getLoc() +"\n"+mLayout.getSceneString() ); + } +} diff --git a/projects/MotionLayoutVerification/app/src/main/java/android/support/constraint/app/VerificationActivity.java b/projects/MotionLayoutVerification/app/src/main/java/android/support/constraint/app/VerificationActivity.java index 3750a16b6..b42db817e 100644 --- a/projects/MotionLayoutVerification/app/src/main/java/android/support/constraint/app/VerificationActivity.java +++ b/projects/MotionLayoutVerification/app/src/main/java/android/support/constraint/app/VerificationActivity.java @@ -97,6 +97,8 @@ public class VerificationActivity extends AppCompatActivity implements View.OnCl activity_map.put("verification_503", FullScreenActivity.class); activity_map.put("v_000", ParseLayouts.class); activity_map.put("verification_800", CheckSetProgress.class); + activity_map.put("basic_cl_001", CheckDumpJson.class); + activity_map.put("basic_cl_002", CheckDumpJson.class); // activity_map.put("verification_037", RotationToolbar.class); @@ -108,8 +110,8 @@ public class VerificationActivity extends AppCompatActivity implements View.OnCl private static boolean REVERSE = false; - private static final String RUN_FIRST = (true) ? "verification_801" : "bug_005"; - private final String LAYOUTS_MATCHES = "v.*_.*"; + private static final String RUN_FIRST = "basic_cl_001";// (true) ? "verification_801" : "bug_005"; + private final String LAYOUTS_MATCHES = "[bv].*_.*"; private static String SHOW_FIRST = ""; MotionLayout mMotionLayout; diff --git a/projects/MotionLayoutVerification/app/src/main/res/layout/basic_cl_001.xml b/projects/MotionLayoutVerification/app/src/main/res/layout/basic_cl_001.xml new file mode 100644 index 000000000..49917f3b3 --- /dev/null +++ b/projects/MotionLayoutVerification/app/src/main/res/layout/basic_cl_001.xml @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/projects/MotionLayoutVerification/app/src/main/res/layout/basic_cl_002.xml b/projects/MotionLayoutVerification/app/src/main/res/layout/basic_cl_002.xml new file mode 100644 index 000000000..ac60078cc --- /dev/null +++ b/projects/MotionLayoutVerification/app/src/main/res/layout/basic_cl_002.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file