Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Register intent-filter to import hprof files #2122

Merged
merged 7 commits into from
May 19, 2021
Merged

Register intent-filter to import hprof files #2122

merged 7 commits into from
May 19, 2021

Conversation

SimonMarquis
Copy link
Contributor

Here is my take on this. Let me know what you think about the implementation.

It uses an intent-filter workaround because of how Android allow us to specify pathPattern (limited regex support and no standard MIME type).
I've also forced to reset to the HeapDumps screen which seems better for what we're trying to achieve here.

I've tested it on Android's file explorer (open with), Google's Files app, and Solid Explorer.

There are 2 possible outcomes when we try to open such files:

  • if there is only a single app supporting the intent, the system opens it immediately
  • otherwise, a disambiguation dialog (the intent chooser) let the user pick an app (demo)
open.hprof.files.mp4

Resolves #2096

if (intent?.action != Intent.ACTION_VIEW) return
val uri = intent.data ?: return
if (uri.lastPathSegment?.endsWith(".hprof") != true) return
resetTo(HeapDumpsScreen())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ok but based on the video there's a little amount of time where one might think they have to click on "import hprof" on that new screen, when in fact the hprof was already being imported. So now I'm wondering if we should add a virtual row for "pending analysis" on that screen (for this new feature but also any time we import).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be a nice addition indeed.
I'll try to look into that, but it seems quite more involving (modifying HeapAnalysisTable.Projection I guess).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we'd want to update the DB as this is very much an "in progress" thing that's only true while the program is running, so we'd risk having out of date info after a restart.

We could probably file this as a follow up... but I'm thinking maybe an internal thing that keeps track of "are we running an analysis right now" and a way to subscribe to that.

@@ -144,7 +156,7 @@ internal class LeakActivity : NavigatingActivity() {
input.copyTo(output, DEFAULT_BUFFER_SIZE)
}
}
HeapAnalyzerService.runAnalysis(this, target)
HeapAnalyzerService.runAnalysis(this, target, heapDumpReason = "Imported by user")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This made me realize I forgot to add a reason when calling it from leakcanary.internal.activity.LeakActivity#importHprof

Ideally we'd differentiate between the two types of import though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I can do that. But for me this is the same reason, but from different paths.
How would you differentiate that? Imported by user / Opened by user.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah actually the words should be the same.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then should we force having to provide a non-null heapDumpReason when calling. And therefore move the "Unknown" fallback to the onHandleIntentInForeground body and fix at the same time the type mismatch Pair<String, String> vs Pair<String, String?> at

metadata = heapAnalysis.metadata + ("Heap dump reason" to heapDumpReason)

@pyricau
Copy link
Member

pyricau commented May 11, 2021

Thx, this is a great PR!

@pyricau
Copy link
Member

pyricau commented May 12, 2021

leakcanary.LeakActivityTest > importHeapDumpFile[test(AVD) - 4.1.2] FAILED 
	androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with text: is "1 Heap Dump"
	If the target view is not part of the view hierarchy, you may need to use Espresso.onData to load it from one of the following AdapterViews:android.widget.ListView@b1831608

@SimonMarquis

This comment has been minimized.

@SimonMarquis

This comment has been minimized.

Comment on lines +99 to +102
LeakCanary.config = LeakCanary.config.copy(onHeapAnalyzedListener = {
DefaultOnHeapAnalyzedListener.create().onHeapAnalyzed(it)
latch.countDown()
})
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pyricau Do you think we should be extra careful here and reset to the default OnHeapAnalyzedListener?
We could either do this in @Before and recreate a new Config or maybe in a JUnit rule?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think we should reset it, yes, though I would do that at the end of the current test, and wrap the whole thing in a run / finally to make sure we reset it even on failures.

Copy link
Contributor Author

@SimonMarquis SimonMarquis May 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the best naming though.
I tried with tryAndRestoreConfig(block: () -> Unit) 35d1d3c.

@pyricau pyricau merged commit 943fd16 into square:main May 19, 2021
@pyricau
Copy link
Member

pyricau commented May 19, 2021

Thanks!

@SimonMarquis SimonMarquis deleted the view_hprof_files branch May 19, 2021 23:41
ghost pushed a commit to shivagowda/leakcanary that referenced this pull request Nov 9, 2021
* Register intent-filter to import hprof files

Relates to square#2096

* Set heapDumpReason to "Imported by user" for imported files

It will be set for both:
- Import Heap Dump action
- Open Heap Dump file

* Test importing hprof file and navigate to HeapDumpScreen

* Show Toast when URI has an unsupported file extension

* Document pathPattern workaround and mention stackoverflow source

* Fix flaky test by waiting for the HeapAnalysis to finish

* Wrap UI test to restore original LeakCanary.config even if it fails
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

LeakCanary should be able to "view" hprof files
2 participants