Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
J
jadx
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
jadx
Commits
e6b91900
Commit
e6b91900
authored
Sep 16, 2014
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gui: add new version notification
parent
ac5a6096
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
428 additions
and
9 deletions
+428
-9
build.gradle
jadx-gui/build.gradle
+1
-0
AboutDialog.java
jadx-gui/src/main/java/jadx/gui/ui/AboutDialog.java
+5
-3
MainWindow.java
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
+24
-6
JadxUpdate.java
jadx-gui/src/main/java/jadx/gui/update/JadxUpdate.java
+105
-0
VersionComparator.java
...-gui/src/main/java/jadx/gui/update/VersionComparator.java
+56
-0
Asset.java
jadx-gui/src/main/java/jadx/gui/update/data/Asset.java
+58
-0
Release.java
jadx-gui/src/main/java/jadx/gui/update/data/Release.java
+56
-0
Link.java
jadx-gui/src/main/java/jadx/gui/utils/Link.java
+90
-0
Messages_en_US.properties
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
+2
-0
TestVersionsComparator.groovy
.../test/groovy/jadx/gui/tests/TestVersionsComparator.groovy
+31
-0
No files found.
jadx-gui/build.gradle
View file @
e6b91900
...
...
@@ -6,6 +6,7 @@ dependencies {
compile
(
project
(
":jadx-core"
))
compile
(
project
(
":jadx-cli"
))
compile
'com.fifesoft:rsyntaxtextarea:2.5.0'
compile
'com.google.code.gson:gson:2.2.4'
}
applicationDistribution
.
with
{
...
...
jadx-gui/src/main/java/jadx/gui/ui/AboutDialog.java
View file @
e6b91900
package
jadx
.
gui
.
ui
;
import
jadx.
core.Jadx
;
import
jadx.
api.JadxDecompiler
;
import
jadx.gui.utils.NLS
;
import
javax.swing.BorderFactory
;
import
javax.swing.Box
;
import
javax.swing.BoxLayout
;
import
javax.swing.JButton
;
...
...
@@ -26,7 +27,7 @@ class AboutDialog extends JDialog {
public
final
void
initUI
()
{
Font
font
=
new
Font
(
"Serif"
,
Font
.
BOLD
,
13
);
JLabel
name
=
new
JLabel
(
"
JADX
"
);
JLabel
name
=
new
JLabel
(
"
jadx
"
);
name
.
setFont
(
font
);
name
.
setAlignmentX
(
0.5f
);
...
...
@@ -34,11 +35,12 @@ class AboutDialog extends JDialog {
desc
.
setFont
(
font
);
desc
.
setAlignmentX
(
0.5f
);
JLabel
version
=
new
JLabel
(
"version: "
+
Jadx
.
getVersion
());
JLabel
version
=
new
JLabel
(
"version: "
+
Jadx
Decompiler
.
getVersion
());
version
.
setFont
(
font
);
version
.
setAlignmentX
(
0.5f
);
JPanel
textPane
=
new
JPanel
();
textPane
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
15
,
15
,
15
,
15
));
textPane
.
setLayout
(
new
BoxLayout
(
textPane
,
BoxLayout
.
PAGE_AXIS
));
textPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
0
,
10
)));
textPane
.
add
(
name
);
...
...
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
View file @
e6b91900
...
...
@@ -4,11 +4,15 @@ import jadx.gui.JadxWrapper;
import
jadx.gui.treemodel.JClass
;
import
jadx.gui.treemodel.JNode
;
import
jadx.gui.treemodel.JRoot
;
import
jadx.gui.update.JadxUpdate
;
import
jadx.gui.update.data.Release
;
import
jadx.gui.utils.JadxPreferences
;
import
jadx.gui.utils.Link
;
import
jadx.gui.utils.NLS
;
import
jadx.gui.utils.Position
;
import
jadx.gui.utils.Utils
;
import
javax.swing.Box
;
import
javax.swing.ImageIcon
;
import
javax.swing.JButton
;
import
javax.swing.JCheckBoxMenuItem
;
...
...
@@ -83,12 +87,25 @@ public class MainWindow extends JFrame {
private
JCheckBoxMenuItem
flatPkgMenuItem
;
private
JToggleButton
flatPkgButton
;
private
boolean
isFlattenPackage
;
private
Link
updateLink
;
public
MainWindow
(
JadxWrapper
wrapper
)
{
this
.
wrapper
=
wrapper
;
initUI
();
initMenuAndToolbar
();
JadxUpdate
.
check
(
new
JadxUpdate
.
IUpdateCallback
()
{
@Override
public
void
onUpdate
(
final
Release
r
)
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
updateLink
.
setText
(
String
.
format
(
NLS
.
str
(
"menu.update_label"
),
r
.
getName
()));
updateLink
.
setVisible
(
true
);
}
});
}
});
}
public
void
openFile
()
{
...
...
@@ -96,16 +113,13 @@ public class MainWindow extends JFrame {
fileChooser
.
setAcceptAllFileFilterUsed
(
true
);
fileChooser
.
setFileFilter
(
new
FileNameExtensionFilter
(
"supported files"
,
"dex"
,
"apk"
,
"jar"
));
fileChooser
.
setToolTipText
(
NLS
.
str
(
"file.open"
));
String
currentDirectory
=
JadxPreferences
.
getLastOpenFilePath
();
if
(!
currentDirectory
.
isEmpty
())
{
fileChooser
.
setCurrentDirectory
(
new
File
(
currentDirectory
));
}
int
ret
=
fileChooser
.
showDialog
(
mainPanel
,
NLS
.
str
(
"file.open"
));
if
(
ret
==
JFileChooser
.
APPROVE_OPTION
)
{
JadxPreferences
.
putLastOpenFilePath
(
fileChooser
.
getCurrentDirectory
().
getPath
());
openFile
(
fileChooser
.
getSelectedFile
());
}
}
...
...
@@ -125,12 +139,11 @@ public class MainWindow extends JFrame {
if
(!
currentDirectory
.
isEmpty
())
{
fileChooser
.
setCurrentDirectory
(
new
File
(
currentDirectory
));
}
int
ret
=
fileChooser
.
showDialog
(
mainPanel
,
NLS
.
str
(
"file.select"
));
if
(
ret
==
JFileChooser
.
APPROVE_OPTION
)
{
JadxPreferences
.
putLastSaveFilePath
(
fileChooser
.
getCurrentDirectory
().
getPath
());
ProgressMonitor
progressMonitor
=
new
ProgressMonitor
(
mainPanel
,
"Saving sources"
,
""
,
0
,
100
);
ProgressMonitor
progressMonitor
=
new
ProgressMonitor
(
mainPanel
,
NLS
.
str
(
"msg.saving_sources"
),
""
,
0
,
100
);
progressMonitor
.
setMillisToPopup
(
500
);
wrapper
.
saveAll
(
fileChooser
.
getSelectedFile
(),
progressMonitor
);
}
...
...
@@ -378,6 +391,11 @@ public class MainWindow extends JFrame {
forwardButton
.
setToolTipText
(
NLS
.
str
(
"nav.forward"
));
toolbar
.
add
(
forwardButton
);
toolbar
.
add
(
Box
.
createHorizontalGlue
());
updateLink
=
new
Link
(
""
,
JadxUpdate
.
JADX_RELEASES_URL
);
updateLink
.
setVisible
(
false
);
toolbar
.
add
(
updateLink
);
mainPanel
.
add
(
toolbar
,
BorderLayout
.
NORTH
);
}
...
...
jadx-gui/src/main/java/jadx/gui/update/JadxUpdate.java
0 → 100644
View file @
e6b91900
package
jadx
.
gui
.
update
;
import
jadx.api.JadxDecompiler
;
import
jadx.gui.update.data.Release
;
import
java.io.InputStreamReader
;
import
java.io.Reader
;
import
java.lang.reflect.Type
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.Iterator
;
import
java.util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.google.gson.Gson
;
import
com.google.gson.reflect.TypeToken
;
public
class
JadxUpdate
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxUpdate
.
class
);
public
static
final
String
JADX_RELEASES_URL
=
"https://github.com/skylot/jadx/releases"
;
private
static
final
String
GITHUB_API_URL
=
"https://api.github.com/"
;
private
static
final
String
GITHUB_RELEASES_URL
=
GITHUB_API_URL
+
"repos/skylot/jadx/releases"
;
private
static
final
Gson
GSON
=
new
Gson
();
private
static
final
Type
RELEASES_LIST_TYPE
=
new
TypeToken
<
List
<
Release
>>()
{}.
getType
();
private
static
final
Comparator
<
Release
>
RELEASE_COMPARATOR
=
new
Comparator
<
Release
>()
{
@Override
public
int
compare
(
Release
o1
,
Release
o2
)
{
return
VersionComparator
.
checkAndCompare
(
o1
.
getName
(),
o2
.
getName
());
}
};
public
static
interface
IUpdateCallback
{
void
onUpdate
(
Release
r
);
}
public
static
void
check
(
final
IUpdateCallback
callback
)
{
Runnable
run
=
new
Runnable
()
{
@Override
public
void
run
()
{
try
{
Release
release
=
checkForNewRelease
();
if
(
release
!=
null
)
{
callback
.
onUpdate
(
release
);
}
}
catch
(
Exception
e
)
{
LOG
.
debug
(
"Jadx update error"
,
e
);
}
}
};
Thread
thread
=
new
Thread
(
run
);
thread
.
setName
(
"Jadx update thread"
);
thread
.
setPriority
(
Thread
.
MIN_PRIORITY
);
thread
.
start
();
}
private
static
Release
checkForNewRelease
()
throws
Exception
{
String
version
=
JadxDecompiler
.
getVersion
();
if
(
version
.
contains
(
"dev"
))
{
LOG
.
debug
(
"Ignore check for update: development version"
);
return
null
;
}
List
<
Release
>
list
=
get
(
GITHUB_RELEASES_URL
,
RELEASES_LIST_TYPE
);
if
(
list
==
null
)
{
return
null
;
}
for
(
Iterator
<
Release
>
it
=
list
.
iterator
();
it
.
hasNext
();
)
{
Release
release
=
it
.
next
();
if
(
release
.
getName
().
equalsIgnoreCase
(
version
)
||
release
.
isPrerelease
())
{
it
.
remove
();
}
}
if
(
list
.
isEmpty
())
{
return
null
;
}
Collections
.
sort
(
list
,
RELEASE_COMPARATOR
);
Release
latest
=
list
.
get
(
list
.
size
()
-
1
);
if
(
VersionComparator
.
checkAndCompare
(
version
,
latest
.
getName
())
==
0
)
{
return
null
;
}
LOG
.
debug
(
"Found new version: {}"
,
latest
);
return
latest
;
}
private
static
<
T
>
T
get
(
String
url
,
Type
type
)
throws
Exception
{
URL
obj
=
new
URL
(
url
);
HttpURLConnection
con
=
(
HttpURLConnection
)
obj
.
openConnection
();
con
.
setRequestMethod
(
"GET"
);
if
(
con
.
getResponseCode
()
==
200
)
{
Reader
reader
=
new
InputStreamReader
(
con
.
getInputStream
());
return
GSON
.
fromJson
(
reader
,
type
);
}
return
null
;
}
}
jadx-gui/src/main/java/jadx/gui/update/VersionComparator.java
0 → 100644
View file @
e6b91900
package
jadx
.
gui
.
update
;
public
class
VersionComparator
{
public
static
int
checkAndCompare
(
String
str1
,
String
str2
)
{
try
{
return
compare
(
clean
(
str1
),
clean
(
str2
));
}
catch
(
NumberFormatException
e
)
{
return
-
2
;
}
}
private
static
String
clean
(
String
str
)
{
String
result
=
str
.
trim
().
toLowerCase
();
if
(
result
.
charAt
(
0
)
==
'v'
)
{
result
=
result
.
substring
(
1
);
}
return
result
;
}
public
static
int
compare
(
String
str1
,
String
str2
)
{
String
[]
s1
=
str1
.
split
(
"\\."
);
int
l1
=
s1
.
length
;
String
[]
s2
=
str2
.
split
(
"\\."
);
int
l2
=
s2
.
length
;
int
i
=
0
;
// skip equals parts
while
(
i
<
l1
&&
i
<
l2
)
{
if
(!
s1
[
i
].
equals
(
s2
[
i
]))
{
break
;
}
i
++;
}
// compare first non-equal ordinal number
if
(
i
<
l1
&&
i
<
l2
)
{
return
Integer
.
valueOf
(
s1
[
i
]).
compareTo
(
Integer
.
valueOf
(
s2
[
i
]));
}
boolean
checkFirst
=
l1
>
l2
;
boolean
zeroTail
=
isZeroTail
(
checkFirst
?
s1
:
s2
,
i
);
if
(
zeroTail
)
{
return
0
;
}
return
checkFirst
?
1
:
-
1
;
}
private
static
boolean
isZeroTail
(
String
[]
arr
,
int
pos
)
{
for
(
int
i
=
pos
;
i
<
arr
.
length
;
i
++)
{
String
s
=
arr
[
i
];
if
(
Integer
.
valueOf
(
s
)
!=
0
)
{
return
false
;
}
}
return
true
;
}
}
jadx-gui/src/main/java/jadx/gui/update/data/Asset.java
0 → 100644
View file @
e6b91900
package
jadx
.
gui
.
update
.
data
;
public
class
Asset
{
private
int
id
;
private
String
url
;
private
String
name
;
private
String
label
;
private
long
size
;
private
int
download_count
;
public
int
getId
()
{
return
id
;
}
public
void
setId
(
int
id
)
{
this
.
id
=
id
;
}
public
String
getUrl
()
{
return
url
;
}
public
void
setUrl
(
String
url
)
{
this
.
url
=
url
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
String
getLabel
()
{
return
label
;
}
public
void
setLabel
(
String
label
)
{
this
.
label
=
label
;
}
public
long
getSize
()
{
return
size
;
}
public
void
setSize
(
long
size
)
{
this
.
size
=
size
;
}
public
int
getDownload_count
()
{
return
download_count
;
}
public
void
setDownload_count
(
int
download_count
)
{
this
.
download_count
=
download_count
;
}
}
jadx-gui/src/main/java/jadx/gui/update/data/Release.java
0 → 100644
View file @
e6b91900
package
jadx
.
gui
.
update
.
data
;
import
java.util.List
;
public
class
Release
{
private
int
id
;
private
String
name
;
private
boolean
prerelease
;
private
List
<
Asset
>
assets
;
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
int
getId
()
{
return
id
;
}
public
void
setId
(
int
id
)
{
this
.
id
=
id
;
}
public
boolean
isPrerelease
()
{
return
prerelease
;
}
public
void
setPrerelease
(
boolean
prerelease
)
{
this
.
prerelease
=
prerelease
;
}
public
List
<
Asset
>
getAssets
()
{
return
assets
;
}
public
void
setAssets
(
List
<
Asset
>
assets
)
{
this
.
assets
=
assets
;
}
@Override
public
String
toString
()
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
name
);
for
(
Asset
asset
:
getAssets
())
{
sb
.
append
(
'\n'
);
sb
.
append
(
" "
).
append
(
asset
.
getName
())
.
append
(
", asset id: "
).
append
(
asset
.
getId
())
.
append
(
", size: "
).
append
(
asset
.
getSize
())
.
append
(
", dc: "
).
append
(
asset
.
getDownload_count
());
}
return
sb
.
toString
();
}
}
jadx-gui/src/main/java/jadx/gui/utils/Link.java
0 → 100644
View file @
e6b91900
package
jadx
.
gui
.
utils
;
import
javax.swing.JLabel
;
import
javax.swing.JOptionPane
;
import
javax.swing.JTextArea
;
import
java.awt.Color
;
import
java.awt.Cursor
;
import
java.awt.Desktop
;
import
java.awt.event.MouseEvent
;
import
java.awt.event.MouseListener
;
import
java.io.IOException
;
import
java.net.URISyntaxException
;
import
java.util.Map
;
import
static
java
.
awt
.
Desktop
.
Action
;
public
class
Link
extends
JLabel
implements
MouseListener
{
private
String
url
;
public
Link
(
String
text
,
String
url
)
{
super
(
text
);
this
.
url
=
url
;
this
.
setToolTipText
(
"Open "
+
url
+
" in your browser"
);
this
.
addMouseListener
(
this
);
this
.
setForeground
(
Color
.
BLUE
);
}
@Override
public
void
mouseClicked
(
MouseEvent
arg0
)
{
browse
();
}
@Override
public
void
mouseEntered
(
MouseEvent
arg0
)
{
setCursor
(
new
Cursor
(
Cursor
.
HAND_CURSOR
));
}
@Override
public
void
mouseExited
(
MouseEvent
arg0
)
{
setCursor
(
new
Cursor
(
Cursor
.
DEFAULT_CURSOR
));
}
@Override
public
void
mousePressed
(
MouseEvent
arg0
)
{
}
@Override
public
void
mouseReleased
(
MouseEvent
arg0
)
{
}
private
void
browse
()
{
if
(
Desktop
.
isDesktopSupported
())
{
Desktop
desktop
=
Desktop
.
getDesktop
();
if
(
desktop
.
isSupported
(
Action
.
BROWSE
))
{
try
{
desktop
.
browse
(
new
java
.
net
.
URI
(
url
));
return
;
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
catch
(
URISyntaxException
e
)
{
e
.
printStackTrace
();
}
}
}
try
{
String
os
=
System
.
getProperty
(
"os.name"
).
toLowerCase
();
if
(
os
.
contains
(
"win"
))
{
Runtime
.
getRuntime
().
exec
(
"rundll32 url.dll,FileProtocolHandler "
+
url
);
return
;
}
if
(
os
.
contains
(
"mac"
))
{
Runtime
.
getRuntime
().
exec
(
"open "
+
url
);
return
;
}
Map
<
String
,
String
>
env
=
System
.
getenv
();
if
(
env
.
get
(
"BROWSER"
)
!=
null
)
{
Runtime
.
getRuntime
().
exec
(
env
.
get
(
"BROWSER"
)
+
" "
+
url
);
return
;
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
showUrlDialog
();
}
private
void
showUrlDialog
()
{
JTextArea
urlArea
=
new
JTextArea
(
"Can't open browser. Please browse to:\n"
+
url
);
JOptionPane
.
showMessageDialog
(
null
,
urlArea
);
}
}
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
View file @
e6b91900
...
...
@@ -7,6 +7,7 @@ menu.search=Search ...
menu.find_in_file
=
Find in ...
menu.help
=
Help
menu.about
=
About
menu.update_label
=
New version %s available!
file.open
=
Open file
file.save
=
Save file
...
...
@@ -43,3 +44,4 @@ search_dialog.field=Field
search_dialog.code
=
Code
msg.open_file
=
Please open file
msg.saving_sources
=
Saving sources
jadx-gui/src/test/groovy/jadx/gui/tests/TestVersionsComparator.groovy
0 → 100644
View file @
e6b91900
package
jadx.gui.tests
import
jadx.gui.update.VersionComparator
import
spock.lang.Specification
class
TestVersionsComparator
extends
Specification
{
def
"test"
()
{
expect:
VersionComparator
.
compare
(
s1
,
s2
)
==
expected
VersionComparator
.
compare
(
s2
,
s1
)
==
-
expected
where:
s1
|
s2
|
expected
""
|
""
|
0
"1"
|
"1"
|
0
"1"
|
"2"
|
-
1
"1.1"
|
"1.1"
|
0
"0.5"
|
"0.5"
|
0
"0.5"
|
"0.5.0"
|
0
"0.5"
|
"0.5.00"
|
0
"0.5"
|
"0.5.0.0"
|
0
"0.5"
|
"0.5.0.1"
|
-
1
"0.5.0"
|
"0.5.0"
|
0
"0.5.0"
|
"0.5.1"
|
-
1
"0.5"
|
"0.5.1"
|
-
1
"0.4.8"
|
"0.5"
|
-
1
"0.4.8"
|
"0.5.0"
|
-
1
"0.4.8"
|
"0.6"
|
-
1
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment