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

Commit

Permalink
Merge 2e594aa into sapling-pr-archive-passy
Browse files Browse the repository at this point in the history
  • Loading branch information
passy authored Mar 25, 2024
2 parents b01b935 + 2e594aa commit 000af7f
Show file tree
Hide file tree
Showing 285 changed files with 5,176 additions and 1,820 deletions.
2 changes: 1 addition & 1 deletion Flipper.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

flipperkit_version = '0.233.0'
flipperkit_version = '0.250.0'
Pod::Spec.new do |spec|
spec.name = 'Flipper'
spec.cocoapods_version = '>= 1.10'
Expand Down
4 changes: 3 additions & 1 deletion FlipperKit.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# LICENSE file in the root directory of this source tree.

folly_compiler_flags = '-DDEBUG=1 -DFLIPPER_OSS=1 -DFB_SONARKIT_ENABLED=1 -DFOLLY_HAVE_BACKTRACE=1 -DFOLLY_HAVE_CLOCK_GETTIME=1 -DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_HAVE_LIBGFLAGS=0 -DFOLLY_HAVE_LIBJEMALLOC=0 -DFOLLY_HAVE_PREADV=0 -DFOLLY_HAVE_PWRITEV=0 -DFOLLY_HAVE_TFO=0 -DFOLLY_USE_SYMBOLIZER=0'
flipperkit_version = '0.233.0'
flipperkit_version = '0.250.0'
Pod::Spec.new do |spec|
spec.name = 'FlipperKit'
spec.version = flipperkit_version
Expand All @@ -18,6 +18,7 @@ Pod::Spec.new do |spec|
spec.module_name = 'FlipperKit'
spec.platforms = { :ios => "11.0" }
spec.default_subspecs = "Core"
spec.frameworks = 'AVFoundation'

# This subspec is necessary since FBDefines.h is imported as <FBDefines/FBDefines.h>
# inside SKMacros.h, which is a public header file. Defining this directory as a
Expand Down Expand Up @@ -77,6 +78,7 @@ Pod::Spec.new do |spec|
ss.dependency 'FlipperKit/FKPortForwarding'
ss.dependency 'Flipper', '~>'+flipperkit_version
ss.dependency 'SocketRocket', '~> 0.7.0'
ss.dependency 'SSZipArchive', '~> 2.4.3'
ss.compiler_flags = folly_compiler_flags
ss.source_files = 'iOS/FlipperKit/*.{h,m,mm}', 'iOS/FlipperKit/CppBridge/*.{h,mm}'
ss.public_header_files = 'iOS/FlipperKit/**/{FlipperDiagnosticsViewController,FlipperStateUpdateListener,FlipperClient,FlipperPlugin,FlipperConnection,FlipperResponder,SKMacros,FlipperKitCertificateProvider}.h'
Expand Down
28 changes: 12 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@ The last Electron release is [v0.239.0](https://github.com/facebook/flipper/rele

### React Native support

If you are debugging React Native applications, v0.239.0 will be the last release with support for it due to technical limitations for React Dev Tools and Hermes Debugger plugins. As such, please refer to that release when debugging React Native applications.
If you are debugging React Native applications, [v0.239.0](https://github.com/facebook/flipper/releases/tag/v0.239.0) will be the last release with support for it due to technical limitations for React Dev Tools and Hermes Debugger plugins. As such, please refer to that release when debugging React Native applications.

New, dedicated debug tooling for React Native is currently being developed at Meta.
In the mean time we recommend this [blog post](https://shift.infinite.red/why-you-dont-need-flipper-in-your-react-native-app-and-how-to-get-by-without-it-3af461955109) with guidance on how to get the capibilities of Flipper through several alternatives.

---

<p align="center">
Flipper (formerly Sonar) is a platform for debugging mobile apps on iOS and Android and JS apps in your browser or in Node.js. Visualize, inspect, and control your apps from a simple desktop interface. Use Flipper as is or extend it using the plugin API.
Flipper is a platform for debugging mobile apps on iOS and Android and JS apps in your browser or in Node.js. Visualize, inspect, and control your apps from a simple desktop interface. Use Flipper as is or extend it using the plugin API.
</p>

![Flipper](website/static/img/inspector.png)
Expand Down Expand Up @@ -83,27 +86,23 @@ This repository includes all parts of Flipper. This includes:
(`/desktop`)
- native Flipper SDKs for iOS (`/iOS`)
- native Flipper SDKs for Android (`/android`)
- cross-platform C++ SDK (`/xplat`)
- React Native Flipper SDK (`/react-native`)
- JS Flipper SDK (`/js`)
- Plugins:
- Logs (`/desktop/plugins/public/logs`)
- Layout inspector (`/desktop/plugins/public/layout`)
- Network inspector (`/desktop/plugins/public/network`)
- Shared Preferences/NSUserDefaults inspector
(`/desktop/plugins/public/shared_preferences`)
- website and documentation (`/website` / `/docs`)
- Plugins (`/desktop/plugins/public/`)
- website and documentation (`/website`, `/docs`)

# Getting started

Please refer to our
[Getting Started guide](https://fbflipper.com/docs/getting-started) to set up
Flipper. Or, (still experimental) run `npx flipper-server` for a browser based
Flipper. Or, run `npx flipper-server` for a browser based
version of Flipper.

## Requirements

- node >= 8
- yarn >= 1.5
- node >= 18
- yarn >= 1.16
- iOS developer tools (for developing iOS plugins)
- Android SDK and adb

Expand All @@ -120,16 +119,13 @@ yarn
yarn start
```

NOTE: If you're on Windows, you need to use Yarn 1.5.1 until
[this issue](https://github.com/yarnpkg/yarn/issues/6048) is resolved.

### Building standalone application

Provide either `--mac`, `--win`, `--linux` or any combination of them to
`yarn build` to build a release zip file for the given platform(s). E.g.

```bash
yarn build --mac --version $buildNumber
yarn build --mac
```

You can find the resulting artifact in the `dist/` folder.
Expand Down
1 change: 1 addition & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ android {
implementation deps.openssl
implementation deps.fbjni
implementation deps.soloader
implementation deps.curtains
implementation deps.jsr305
implementation deps.supportAppCompat
implementation deps.supportSqlite
Expand Down
9 changes: 6 additions & 3 deletions android/plugins/jetpack-compose/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ android {

dependencies {
implementation project(':android')
implementation 'androidx.compose.ui:ui:1.4.3'
implementation 'androidx.compose.ui:ui-tooling:1.4.3'
implementation 'org.jetbrains.kotlin:kotlin-reflect:1.9.21'
implementation "androidx.compose.ui:ui:$COMPOSE_VERSION"
implementation "androidx.compose.ui:ui-tooling:$COMPOSE_VERSION"
implementation "androidx.compose.ui:ui-tooling-data:$COMPOSE_VERSION"
implementation "org.jetbrains.kotlin:kotlin-reflect:$KOTLIN_VERSION"
implementation "androidx.collection:collection-ktx:1.4.0"
implementation project(':inspection-lib')
implementation deps.soloader
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,58 @@

package com.facebook.flipper.plugins.jetpackcompose

import androidx.compose.ui.platform.ComposeView
import com.facebook.flipper.plugins.jetpackcompose.descriptors.*
import com.facebook.flipper.plugins.jetpackcompose.model.*
import android.os.Build
import android.util.Log
import androidx.compose.ui.platform.AbstractComposeView
import androidx.compose.ui.platform.isDebugInspectorInfoEnabled
import com.facebook.flipper.plugins.jetpackcompose.descriptors.AbstractComposeViewDescriptor
import com.facebook.flipper.plugins.jetpackcompose.descriptors.ComposeInnerViewDescriptor
import com.facebook.flipper.plugins.jetpackcompose.descriptors.ComposeNodeDescriptor
import com.facebook.flipper.plugins.jetpackcompose.model.ComposeInnerViewNode
import com.facebook.flipper.plugins.jetpackcompose.model.ComposeNode
import com.facebook.flipper.plugins.uidebugger.core.UIDContext
import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister
import com.facebook.soloader.SoLoader

const val JetpackComposeTag = "JetpackCompose"
const val JetpackComposeTag = "Compose"

object UIDebuggerComposeSupport {

private const val TAG = "UIDebuggerCompose"

init {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
try {
SoLoader.loadLibrary("art_tooling")
} catch (t: Throwable) {
Log.e(TAG, "Failed to load native library.", t)
}
enableDebugInspectorInfo()
}
}

fun enable(context: UIDContext) {
addDescriptors(context.descriptorRegister)
}

private fun addDescriptors(register: DescriptorRegister) {
register.register(ComposeView::class.java, ComposeViewDescriptor)
register.register(AbstractComposeView::class.java, AbstractComposeViewDescriptor)
register.register(ComposeNode::class.java, ComposeNodeDescriptor)
register.register(ComposeInnerViewNode::class.java, ComposeInnerViewDescriptor)
}

private fun enableDebugInspectorInfo() {
// Set isDebugInspectorInfoEnabled to true via reflection such that Redex and R8 cannot see the
// assignment. This allows the InspectorInfo lambdas to be stripped from release builds.
if (!isDebugInspectorInfoEnabled) {
try {
val packageClass = Class.forName("androidx.compose.ui.platform.InspectableValueKt")
val field = packageClass.getDeclaredField("isDebugInspectorInfoEnabled")
field.isAccessible = true
field.setBoolean(null, true)
} catch (ex: Exception) {
Log.e(TAG, "Could not access isDebugInspectorInfoEnabled.", ex)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* 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.jetpackcompose.descriptors

import android.os.Build
import android.os.Debug
import android.util.Log
import android.view.View
import androidx.annotation.RequiresApi
import androidx.compose.ui.platform.AbstractComposeView
import androidx.inspection.DefaultArtTooling
import com.facebook.flipper.plugins.jetpackcompose.model.ComposeNode
import com.facebook.flipper.plugins.uidebugger.descriptors.ChainedDescriptor
import com.facebook.flipper.plugins.uidebugger.descriptors.WarningMessage
import facebook.internal.androidx.compose.ui.inspection.RecompositionHandler
import facebook.internal.androidx.compose.ui.inspection.inspector.InspectorNode
import facebook.internal.androidx.compose.ui.inspection.inspector.LayoutInspectorTree
import java.io.IOException

object AbstractComposeViewDescriptor : ChainedDescriptor<AbstractComposeView>() {
private val recompositionHandler by lazy {
RecompositionHandler(DefaultArtTooling("Flipper")).apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
attachJvmtiAgent()
startTrackingRecompositions(this)
}
}
}

override fun onGetName(node: AbstractComposeView): String = node.javaClass.simpleName

private fun transform(
view: View,
nodes: List<InspectorNode>,
layoutInspectorTree: LayoutInspectorTree
): List<ComposeNode> {
val positionOnScreen = IntArray(2)
view.getLocationInWindow(positionOnScreen)

val xOffset = positionOnScreen[0]
val yOffset = positionOnScreen[1]

return nodes.map { node ->
ComposeNode(view, layoutInspectorTree, recompositionHandler, node, xOffset, yOffset)
}
}

override fun onGetChildren(node: AbstractComposeView): List<Any> {
val children = mutableListOf<Any>()
val count = node.childCount - 1
for (i in 0..count) {
val child: View = node.getChildAt(i)
children.add(child)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val layoutInspector = LayoutInspectorTree()
layoutInspector.hideSystemNodes = true
val composeNodes =
try {
transform(child, layoutInspector.convert(child), layoutInspector)
} catch (t: Throwable) {
listOf(
WarningMessage(
"Unknown error occurred while trying to inspect compose node: ${t.message}",
getBounds(node)))
}
return if (composeNodes.isNullOrEmpty()) {
listOf(
WarningMessage(
"Go to developer options and make sure that \"Enable view attribute inspection\" option is enabled.",
getBounds(node)))
} else {
composeNodes
}
}
}

return children
}

@RequiresApi(Build.VERSION_CODES.Q)
private fun attachJvmtiAgent() {
try {
Debug.attachJvmtiAgent("nonexistent.so", null, null)
} catch (e: IOException) {
// expected: "nonexistent.so" doesn't exist, however attachJvmtiAgent call is enough
// to make art to load JVMTI plugin.
}
}

private fun startTrackingRecompositions(recompositionHandler: RecompositionHandler) {
try {
recompositionHandler.changeCollectionMode(startCollecting = true, keepCounts = true)
} catch (t: Throwable) {
Log.e("ComposeViewDescriptor", "Failed to start tracking recompositions", t)
}
}
}
Loading

0 comments on commit 000af7f

Please sign in to comment.