Skip to content
This repository was archived by the owner on Nov 22, 2024. It is now read-only.

Commit 892ff99

Browse files
authored
Merge 3ff7535 into sapling-pr-archive-passy
2 parents 839d7b8 + 3ff7535 commit 892ff99

File tree

154 files changed

+1026
-6941
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

154 files changed

+1026
-6941
lines changed
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: facebook/flipper/build-and-deploy
2+
on:
3+
push:
4+
branches:
5+
- main
6+
env:
7+
ANDROID_PUBLISH_KEY: ${{ secrets.ANDROID_PUBLISH_KEY }}
8+
jobs:
9+
snapshot:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- name: Install Dependencies
14+
run: |
15+
sudo apt-get update
16+
sudo apt-get install -y sdkmanager
17+
- name: Install JDK
18+
uses: actions/setup-java@v4
19+
with:
20+
java-version: '17'
21+
distribution: 'temurin'
22+
cache: gradle
23+
- name: Install Retry
24+
run: scripts/install-retry.sh
25+
- name: Build
26+
run: |
27+
yes | sdkmanager "platforms;android-33" || true
28+
/tmp/retry -m 3 ./gradlew :android:assembleRelease --info
29+
- name: Deploy Snapshot
30+
run: "/tmp/retry -m 3 scripts/publish-android-snapshot.sh"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.flipper.plugins.uidebugger.litho
9+
10+
import com.facebook.inject.statics.BoundSetStatic
11+
import com.facebook.litho.DebugComponent
12+
import kotlinx.serialization.json.JsonObject
13+
14+
@BoundSetStatic
15+
interface ILithoDebugComponentDescriptorExtension {
16+
fun getExtraTags(node: DebugComponent): Set<String>?
17+
18+
fun getExtraHiddenAttributes(node: DebugComponent): JsonObject?
19+
}

android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/DebugComponentDescriptor.kt

+26-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import com.facebook.flipper.plugins.uidebugger.descriptors.Id
1616
import com.facebook.flipper.plugins.uidebugger.descriptors.MetadataRegister
1717
import com.facebook.flipper.plugins.uidebugger.descriptors.NodeDescriptor
1818
import com.facebook.flipper.plugins.uidebugger.descriptors.OffsetChild
19+
import com.facebook.flipper.plugins.uidebugger.litho.ILithoDebugComponentDescriptorExtensionStatic
1920
import com.facebook.flipper.plugins.uidebugger.litho.LithoMountableTag
2021
import com.facebook.flipper.plugins.uidebugger.litho.LithoTag
2122
import com.facebook.flipper.plugins.uidebugger.litho.descriptors.props.ComponentDataExtractor
@@ -40,6 +41,7 @@ import com.facebook.litho.widget.RecyclerBinder
4041
import com.facebook.rendercore.FastMath
4142
import com.facebook.yoga.YogaEdge
4243
import java.lang.reflect.Modifier
44+
import kotlinx.serialization.json.JsonObject
4345

4446
typealias GlobalKey = String
4547

@@ -247,7 +249,14 @@ class DebugComponentDescriptor(val register: DescriptorRegister) : NodeDescripto
247249
Bounds.fromRect(node.boundsInParentDebugComponent)
248250

249251
override fun getTags(node: DebugComponent): Set<String> {
250-
val tags = mutableSetOf(LithoTag)
252+
val tags: MutableSet<String> = mutableSetOf(LithoTag)
253+
254+
for (id in ILithoDebugComponentDescriptorExtensionStatic.getKeys()) {
255+
val extraTags = ILithoDebugComponentDescriptorExtensionStatic.getExtraTags(id, node)
256+
if (extraTags != null) {
257+
tags.addAll(extraTags)
258+
}
259+
}
251260

252261
if (node.component.mountType != Component.MountType.NONE) {
253262
tags.add(LithoMountableTag)
@@ -303,6 +312,22 @@ class DebugComponentDescriptor(val register: DescriptorRegister) : NodeDescripto
303312
return mountingData
304313
}
305314

315+
private fun mergeJsonObjects(obj1: JsonObject, obj2: JsonObject): JsonObject {
316+
return JsonObject(obj1.toMap() + obj2.toMap())
317+
}
318+
319+
override fun getHiddenAttributes(node: DebugComponent): JsonObject? {
320+
var hiddenAttributes = JsonObject(mapOf())
321+
for (id in ILithoDebugComponentDescriptorExtensionStatic.getKeys()) {
322+
val extraHiddenAttributes =
323+
ILithoDebugComponentDescriptorExtensionStatic.getExtraHiddenAttributes(id, node)
324+
if (extraHiddenAttributes != null) {
325+
hiddenAttributes = mergeJsonObjects(hiddenAttributes, extraHiddenAttributes)
326+
}
327+
}
328+
return hiddenAttributes
329+
}
330+
306331
class OverrideData(
307332
val metadataPath: List<Metadata>,
308333
val value: FlipperDynamic,

android/src/main/java/com/facebook/flipper/plugins/inspector/InspectorValue.java

-88
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,7 @@
99

1010
import com.facebook.flipper.core.FlipperObject;
1111
import com.facebook.flipper.core.FlipperValue;
12-
import java.util.Collections;
13-
import java.util.Comparator;
14-
import java.util.List;
15-
import java.util.Map;
1612
import java.util.Set;
17-
import org.json.JSONArray;
18-
import org.json.JSONException;
19-
import org.json.JSONObject;
2013

2114
public class InspectorValue<T> implements FlipperValue {
2215

@@ -37,7 +30,6 @@ public static class Type<T> {
3730
public static final Type<String> Enum = new Type<>("enum");
3831
public static final Type<Integer> Color = new Type<>("color");
3932
public static final Type<Picker> Picker = new Type<>("picker");
40-
public static final Type<Timeline> Timeline = new Type<>("timeline");
4133

4234
private final String mName;
4335

@@ -116,84 +108,4 @@ public String toString() {
116108
return b.toString();
117109
}
118110
}
119-
120-
/**
121-
* A widget that represents a timeline. Each point has a moment to be placed on the timeline, and
122-
* a key to be identified as. The current field represents the key of the point in the timeline
123-
* that matches the current moment in time.
124-
*/
125-
public static final class Timeline {
126-
public final List<TimePoint> time;
127-
public final String current;
128-
129-
public Timeline(List<TimePoint> time, String current) {
130-
Collections.sort(
131-
time,
132-
new Comparator<TimePoint>() {
133-
@Override
134-
public int compare(TimePoint stringTimePointEntry, TimePoint t1) {
135-
return Float.compare(stringTimePointEntry.moment, t1.moment);
136-
}
137-
});
138-
this.time = time;
139-
this.current = current;
140-
}
141-
142-
private JSONObject toJson() {
143-
final JSONArray points = new JSONArray();
144-
for (TimePoint value : time) {
145-
points.put(value.toJson());
146-
}
147-
try {
148-
return new JSONObject().put("time", points).put("current", current);
149-
} catch (JSONException t) {
150-
throw new RuntimeException(t);
151-
}
152-
}
153-
154-
@Override
155-
public String toString() {
156-
return toJson().toString();
157-
}
158-
159-
/**
160-
* An entry in the timeline, identified by its key. They're sorted in Flipper by moment, and are
161-
* rendered according to the display and color. Any additional properties attached to the point
162-
* will be displayed when it's selected.
163-
*/
164-
public static final class TimePoint {
165-
public final long moment;
166-
public final String display;
167-
public final String color;
168-
public final String key;
169-
public final Map<String, String> properties;
170-
171-
public TimePoint(
172-
String key, long moment, String display, String color, Map<String, String> properties) {
173-
this.key = key;
174-
this.moment = moment;
175-
this.display = display;
176-
this.color = color;
177-
this.properties = properties;
178-
}
179-
180-
private JSONObject toJson() {
181-
try {
182-
return new JSONObject()
183-
.put("moment", moment)
184-
.put("display", display)
185-
.put("color", color)
186-
.put("key", key)
187-
.put("properties", new JSONObject(properties));
188-
} catch (JSONException t) {
189-
throw new RuntimeException(t);
190-
}
191-
}
192-
193-
@Override
194-
public String toString() {
195-
return toJson().toString();
196-
}
197-
}
198-
}
199111
}

android/src/main/java/com/facebook/flipper/plugins/uidebugger/commands/Command.kt

+2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ import com.facebook.flipper.plugins.uidebugger.core.UIDContext
1717
abstract class Command(val context: UIDContext) {
1818
/** The command identifier to respond to */
1919
abstract fun identifier(): String
20+
2021
/** Execute the command */
2122
abstract fun execute(params: FlipperObject, response: FlipperResponder)
23+
2224
/** Receiver which is the low-level handler for the incoming request */
2325
open fun receiver(): FlipperReceiver {
2426
return object : MainThreadFlipperReceiver() {

android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ class ApplicationRef(val application: Application) {
2020
// the root view resolver will at least find the decor view, this is the case for various
2121
// kinds of custom overlays
2222
// 2. Dialog fragments
23-
val rootsResolver: RootViewResolver = RootViewResolver()
2423
val windowManagerUtility = WindowManagerUtility()
2524
val activitiesStack: List<Activity>
2625
get() {

android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt

+49-42
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import com.facebook.flipper.plugins.uidebugger.descriptors.ViewDescriptor
1717
import com.facebook.flipper.plugins.uidebugger.util.StopWatch
1818
import com.facebook.flipper.plugins.uidebugger.util.Throttler
1919
import com.facebook.flipper.plugins.uidebugger.util.objectIdentity
20+
import curtains.Curtains
21+
import curtains.OnRootViewsChangedListener
2022

2123
/**
2224
* The UIDebugger does 3 things:
@@ -44,61 +46,66 @@ class DecorViewTracker(private val context: UIDContext, private val snapshotter:
4446

4547
fun start() {
4648

47-
val applicationRef = context.applicationRef
48-
49-
val rootViewListener =
50-
object : RootViewResolver.Listener {
51-
override fun onRootViewAdded(rootView: View) {}
52-
53-
override fun onRootViewRemoved(rootView: View) {}
54-
55-
override fun onRootViewsChanged(rootViews: List<View>) {
56-
// remove predraw listen from current view as its going away or will be covered
57-
Log.i(LogTag, "Removing pre draw listener from ${currentDecorView?.objectIdentity()}")
58-
currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener)
49+
val rootViewChangedListener = OnRootViewsChangedListener { view, added ->
50+
if (currentDecorView != null) {
51+
// remove predraw listen from current view as its going away or will be covered
52+
Log.d(LogTag, "Removing pre draw listener from ${currentDecorView?.objectIdentity()}")
53+
currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener)
54+
}
55+
56+
val decorViewToActivity: Map<View, Activity> = ActivityTracker.decorViewToActivityMap
57+
58+
// at the time of this callback curtains.rootViews is not updated yet, so we need to use the
59+
// 'view' and 'added' params to the callback to see any new root views
60+
val topView =
61+
if (added && ApplicationRefDescriptor.isUsefulRoot(decorViewToActivity[view] ?: view)) {
62+
view
63+
} else {
64+
// this is technically the preview set of root view but this is the branch where the new
65+
// root view is not 'useful' or we are popping a view off the stack so the old roots are
66+
// fine here
67+
Curtains.rootViews.lastOrNull {
68+
ApplicationRefDescriptor.isUsefulRoot(decorViewToActivity[it] ?: it)
69+
}
70+
}
5971

60-
// setup new listener on top most view, that will be the active child in traversal
72+
if (topView != null) {
73+
val throttler = Throttler(500) { currentDecorView?.let { traverseSnapshotAndSend(it) } }
6174

62-
val decorViewToActivity: Map<View, Activity> = ActivityTracker.decorViewToActivityMap
75+
preDrawListener =
76+
ViewTreeObserver.OnPreDrawListener {
77+
throttler.trigger()
78+
true
79+
}
6380

64-
val topView =
65-
rootViews.lastOrNull { view ->
66-
val activityOrView = decorViewToActivity[view] ?: view
67-
ApplicationRefDescriptor.isUsefulRoot(activityOrView)
68-
}
81+
topView.viewTreeObserver.addOnPreDrawListener(preDrawListener)
82+
currentDecorView = topView
6983

70-
if (topView != null) {
71-
val throttler =
72-
Throttler(500) { currentDecorView?.let { traverseSnapshotAndSend(it) } }
84+
Log.i(LogTag, "Added pre draw listener to ${topView.objectIdentity()}")
7385

74-
preDrawListener =
75-
ViewTreeObserver.OnPreDrawListener {
76-
throttler.trigger()
77-
true
78-
}
86+
// schedule traversal immediately when we detect a new decor view
87+
throttler.trigger()
88+
}
89+
}
7990

80-
topView.viewTreeObserver.addOnPreDrawListener(preDrawListener)
81-
currentDecorView = topView
91+
Curtains.onRootViewsChangedListeners.add(rootViewChangedListener)
8292

83-
Log.i(LogTag, "Added pre draw listener to ${topView.objectIdentity()}")
93+
// On subscribe, trigger a traversal on whatever roots we have
94+
val decorViewToActivity: Map<View, Activity> = ActivityTracker.decorViewToActivityMap
8495

85-
// schedule traversal immediately when we detect a new decor view
86-
throttler.trigger()
87-
}
88-
}
96+
val topView =
97+
Curtains.rootViews.lastOrNull {
98+
ApplicationRefDescriptor.isUsefulRoot(decorViewToActivity[it] ?: it)
8999
}
100+
if (topView != null) {
101+
rootViewChangedListener.onRootViewsChanged(topView, true)
102+
}
90103

91-
context.applicationRef.rootsResolver.attachListener(rootViewListener)
92-
// On subscribe, trigger a traversal on whatever roots we have
93-
rootViewListener.onRootViewsChanged(applicationRef.rootsResolver.rootViews())
94-
95-
Log.i(
96-
LogTag,
97-
"Starting tracking root views, currently ${context.applicationRef.rootsResolver.rootViews().size} root views")
104+
Log.i(LogTag, "Starting tracking root views, currently ${Curtains.rootViews.size} root views")
98105
}
99106

100107
fun stop() {
101-
context.applicationRef.rootsResolver.attachListener(null)
108+
Curtains.onRootViewsChangedListeners.clear()
102109
currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener)
103110
currentDecorView = null
104111
preDrawListener = null

0 commit comments

Comments
 (0)