Skip to content

Commit

Permalink
Merge 3ff7535 into sapling-pr-archive-passy
Browse files Browse the repository at this point in the history
  • Loading branch information
passy authored May 7, 2024
2 parents 839d7b8 + 3ff7535 commit 892ff99
Show file tree
Hide file tree
Showing 154 changed files with 1,026 additions and 6,941 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: facebook/flipper/build-and-deploy
on:
push:
branches:
- main
env:
ANDROID_PUBLISH_KEY: ${{ secrets.ANDROID_PUBLISH_KEY }}
jobs:
snapshot:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y sdkmanager
- name: Install JDK
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: gradle
- name: Install Retry
run: scripts/install-retry.sh
- name: Build
run: |
yes | sdkmanager "platforms;android-33" || true
/tmp/retry -m 3 ./gradlew :android:assembleRelease --info
- name: Deploy Snapshot
run: "/tmp/retry -m 3 scripts/publish-android-snapshot.sh"
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

package com.facebook.flipper.plugins.uidebugger.litho

import com.facebook.inject.statics.BoundSetStatic
import com.facebook.litho.DebugComponent
import kotlinx.serialization.json.JsonObject

@BoundSetStatic
interface ILithoDebugComponentDescriptorExtension {
fun getExtraTags(node: DebugComponent): Set<String>?

fun getExtraHiddenAttributes(node: DebugComponent): JsonObject?
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.facebook.flipper.plugins.uidebugger.descriptors.Id
import com.facebook.flipper.plugins.uidebugger.descriptors.MetadataRegister
import com.facebook.flipper.plugins.uidebugger.descriptors.NodeDescriptor
import com.facebook.flipper.plugins.uidebugger.descriptors.OffsetChild
import com.facebook.flipper.plugins.uidebugger.litho.ILithoDebugComponentDescriptorExtensionStatic
import com.facebook.flipper.plugins.uidebugger.litho.LithoMountableTag
import com.facebook.flipper.plugins.uidebugger.litho.LithoTag
import com.facebook.flipper.plugins.uidebugger.litho.descriptors.props.ComponentDataExtractor
Expand All @@ -40,6 +41,7 @@ import com.facebook.litho.widget.RecyclerBinder
import com.facebook.rendercore.FastMath
import com.facebook.yoga.YogaEdge
import java.lang.reflect.Modifier
import kotlinx.serialization.json.JsonObject

typealias GlobalKey = String

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

override fun getTags(node: DebugComponent): Set<String> {
val tags = mutableSetOf(LithoTag)
val tags: MutableSet<String> = mutableSetOf(LithoTag)

for (id in ILithoDebugComponentDescriptorExtensionStatic.getKeys()) {
val extraTags = ILithoDebugComponentDescriptorExtensionStatic.getExtraTags(id, node)
if (extraTags != null) {
tags.addAll(extraTags)
}
}

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

private fun mergeJsonObjects(obj1: JsonObject, obj2: JsonObject): JsonObject {
return JsonObject(obj1.toMap() + obj2.toMap())
}

override fun getHiddenAttributes(node: DebugComponent): JsonObject? {
var hiddenAttributes = JsonObject(mapOf())
for (id in ILithoDebugComponentDescriptorExtensionStatic.getKeys()) {
val extraHiddenAttributes =
ILithoDebugComponentDescriptorExtensionStatic.getExtraHiddenAttributes(id, node)
if (extraHiddenAttributes != null) {
hiddenAttributes = mergeJsonObjects(hiddenAttributes, extraHiddenAttributes)
}
}
return hiddenAttributes
}

class OverrideData(
val metadataPath: List<Metadata>,
val value: FlipperDynamic,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,7 @@

import com.facebook.flipper.core.FlipperObject;
import com.facebook.flipper.core.FlipperValue;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class InspectorValue<T> implements FlipperValue {

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

private final String mName;

Expand Down Expand Up @@ -116,84 +108,4 @@ public String toString() {
return b.toString();
}
}

/**
* A widget that represents a timeline. Each point has a moment to be placed on the timeline, and
* a key to be identified as. The current field represents the key of the point in the timeline
* that matches the current moment in time.
*/
public static final class Timeline {
public final List<TimePoint> time;
public final String current;

public Timeline(List<TimePoint> time, String current) {
Collections.sort(
time,
new Comparator<TimePoint>() {
@Override
public int compare(TimePoint stringTimePointEntry, TimePoint t1) {
return Float.compare(stringTimePointEntry.moment, t1.moment);
}
});
this.time = time;
this.current = current;
}

private JSONObject toJson() {
final JSONArray points = new JSONArray();
for (TimePoint value : time) {
points.put(value.toJson());
}
try {
return new JSONObject().put("time", points).put("current", current);
} catch (JSONException t) {
throw new RuntimeException(t);
}
}

@Override
public String toString() {
return toJson().toString();
}

/**
* An entry in the timeline, identified by its key. They're sorted in Flipper by moment, and are
* rendered according to the display and color. Any additional properties attached to the point
* will be displayed when it's selected.
*/
public static final class TimePoint {
public final long moment;
public final String display;
public final String color;
public final String key;
public final Map<String, String> properties;

public TimePoint(
String key, long moment, String display, String color, Map<String, String> properties) {
this.key = key;
this.moment = moment;
this.display = display;
this.color = color;
this.properties = properties;
}

private JSONObject toJson() {
try {
return new JSONObject()
.put("moment", moment)
.put("display", display)
.put("color", color)
.put("key", key)
.put("properties", new JSONObject(properties));
} catch (JSONException t) {
throw new RuntimeException(t);
}
}

@Override
public String toString() {
return toJson().toString();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import com.facebook.flipper.plugins.uidebugger.core.UIDContext
abstract class Command(val context: UIDContext) {
/** The command identifier to respond to */
abstract fun identifier(): String

/** Execute the command */
abstract fun execute(params: FlipperObject, response: FlipperResponder)

/** Receiver which is the low-level handler for the incoming request */
open fun receiver(): FlipperReceiver {
return object : MainThreadFlipperReceiver() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class ApplicationRef(val application: Application) {
// the root view resolver will at least find the decor view, this is the case for various
// kinds of custom overlays
// 2. Dialog fragments
val rootsResolver: RootViewResolver = RootViewResolver()
val windowManagerUtility = WindowManagerUtility()
val activitiesStack: List<Activity>
get() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import com.facebook.flipper.plugins.uidebugger.descriptors.ViewDescriptor
import com.facebook.flipper.plugins.uidebugger.util.StopWatch
import com.facebook.flipper.plugins.uidebugger.util.Throttler
import com.facebook.flipper.plugins.uidebugger.util.objectIdentity
import curtains.Curtains
import curtains.OnRootViewsChangedListener

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

fun start() {

val applicationRef = context.applicationRef

val rootViewListener =
object : RootViewResolver.Listener {
override fun onRootViewAdded(rootView: View) {}

override fun onRootViewRemoved(rootView: View) {}

override fun onRootViewsChanged(rootViews: List<View>) {
// remove predraw listen from current view as its going away or will be covered
Log.i(LogTag, "Removing pre draw listener from ${currentDecorView?.objectIdentity()}")
currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener)
val rootViewChangedListener = OnRootViewsChangedListener { view, added ->
if (currentDecorView != null) {
// remove predraw listen from current view as its going away or will be covered
Log.d(LogTag, "Removing pre draw listener from ${currentDecorView?.objectIdentity()}")
currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener)
}

val decorViewToActivity: Map<View, Activity> = ActivityTracker.decorViewToActivityMap

// at the time of this callback curtains.rootViews is not updated yet, so we need to use the
// 'view' and 'added' params to the callback to see any new root views
val topView =
if (added && ApplicationRefDescriptor.isUsefulRoot(decorViewToActivity[view] ?: view)) {
view
} else {
// this is technically the preview set of root view but this is the branch where the new
// root view is not 'useful' or we are popping a view off the stack so the old roots are
// fine here
Curtains.rootViews.lastOrNull {
ApplicationRefDescriptor.isUsefulRoot(decorViewToActivity[it] ?: it)
}
}

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

val decorViewToActivity: Map<View, Activity> = ActivityTracker.decorViewToActivityMap
preDrawListener =
ViewTreeObserver.OnPreDrawListener {
throttler.trigger()
true
}

val topView =
rootViews.lastOrNull { view ->
val activityOrView = decorViewToActivity[view] ?: view
ApplicationRefDescriptor.isUsefulRoot(activityOrView)
}
topView.viewTreeObserver.addOnPreDrawListener(preDrawListener)
currentDecorView = topView

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

preDrawListener =
ViewTreeObserver.OnPreDrawListener {
throttler.trigger()
true
}
// schedule traversal immediately when we detect a new decor view
throttler.trigger()
}
}

topView.viewTreeObserver.addOnPreDrawListener(preDrawListener)
currentDecorView = topView
Curtains.onRootViewsChangedListeners.add(rootViewChangedListener)

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

// schedule traversal immediately when we detect a new decor view
throttler.trigger()
}
}
val topView =
Curtains.rootViews.lastOrNull {
ApplicationRefDescriptor.isUsefulRoot(decorViewToActivity[it] ?: it)
}
if (topView != null) {
rootViewChangedListener.onRootViewsChanged(topView, true)
}

context.applicationRef.rootsResolver.attachListener(rootViewListener)
// On subscribe, trigger a traversal on whatever roots we have
rootViewListener.onRootViewsChanged(applicationRef.rootsResolver.rootViews())

Log.i(
LogTag,
"Starting tracking root views, currently ${context.applicationRef.rootsResolver.rootViews().size} root views")
Log.i(LogTag, "Starting tracking root views, currently ${Curtains.rootViews.size} root views")
}

fun stop() {
context.applicationRef.rootsResolver.attachListener(null)
Curtains.onRootViewsChangedListeners.clear()
currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener)
currentDecorView = null
preDrawListener = null
Expand Down
Loading

0 comments on commit 892ff99

Please sign in to comment.