app-info 2.7.0.beta5 → 2.8.2.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -1
- data/README.md +32 -20
- data/Rakefile +1 -0
- data/app_info.gemspec +3 -3
- data/lib/app_info/aab.rb +24 -5
- data/lib/app_info/apk.rb +24 -30
- data/lib/app_info/protobuf/manifest.rb +81 -2
- data/lib/app_info/version.rb +1 -1
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acae0e6afac09e51c307232f2f6fbb7b9c5d8164cfcb04b41399129213b94790
|
4
|
+
data.tar.gz: ce8d5c78d09665d5b28341ad9a3a436ab8da67dd6d6de64c58ac293afce16393
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f33fda6c627d595056189fb41d1b2807104a0de328a80d96cd866d03ad1d894025610a077a20e8f4b700185ce0f72b656fbd642996dc85e7399b92f1a043a409
|
7
|
+
data.tar.gz: af45f63c197b3c5490a597aedf438f14af63ee997dbc1c589240dba2aa4225067e8183d38d9d299058891dc83b4adff740f8834e1e06fe7b6da412ef8d0ad555
|
data/CHANGELOG.md
CHANGED
@@ -9,6 +9,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
9
9
|
|
10
10
|
> List all changes before release a new version.
|
11
11
|
|
12
|
+
## [2.8.1] (2021-12-20)
|
13
|
+
|
14
|
+
### Fixed
|
15
|
+
|
16
|
+
- Fix no found intent filter in manifest error.
|
17
|
+
|
18
|
+
## [2.8.0] (2021-12-16)
|
19
|
+
|
20
|
+
### Added
|
21
|
+
|
22
|
+
- New methods added to `apk` and `aab` [3adfa223](https://github.com/icyleaf/app_info/tree/3adfa223479caa672fce5d3a119b6db098463699) [939a6506](https://github.com/icyleaf/app_info/tree/939a6506f3ac1cb7ad1ed46128df41de6ee3b0d0)
|
23
|
+
|
24
|
+
## [2.7.0] (2021-10-15)
|
25
|
+
|
26
|
+
### Added
|
27
|
+
|
28
|
+
- Android App Bundle (a.k.a) aab support!!! parts support [#36](https://github.com/icyleaf/app_info/pull/36)
|
29
|
+
|
12
30
|
## [2.7.0.beta5] (2021-10-14)
|
13
31
|
|
14
32
|
### Fixed
|
@@ -204,7 +222,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
204
222
|
|
205
223
|
- Updated dependency of CFPropertly list be a range between 2.3.4. (thanks @[cschroed](https://github.com/cschroed))
|
206
224
|
|
207
|
-
[Unreleased]: https://github.com/icyleaf/app-info/compare/v2.
|
225
|
+
[Unreleased]: https://github.com/icyleaf/app-info/compare/v2.8.1..HEAD
|
226
|
+
[2.8.1]: https://github.com/icyleaf/app-info/compare/v2.8.0...v2.8.1
|
227
|
+
[2.8.0]: https://github.com/icyleaf/app-info/compare/v2.7.0...v2.8.0
|
228
|
+
[2.7.0]: https://github.com/icyleaf/app-info/compare/v2.6.5...v2.7.0
|
208
229
|
[2.7.0.beta5]: https://github.com/icyleaf/app-info/compare/v2.7.0.beta2...v2.7.0.beta5
|
209
230
|
[2.7.0.beta2]: https://github.com/icyleaf/app-info/compare/v2.7.0.beta1...v2.7.0.beta2
|
210
231
|
[2.7.0.beta1]: https://github.com/icyleaf/app-info/compare/v2.6.5...v2.7.0.beta1
|
data/README.md
CHANGED
@@ -49,6 +49,7 @@ require 'app-info'
|
|
49
49
|
parser = AppInfo.parse('iphone.ipa')
|
50
50
|
parser = AppInfo.parse('ipad.ipa')
|
51
51
|
parser = AppInfo.parse('android.apk')
|
52
|
+
parser = AppInfo.parse('android.aab')
|
52
53
|
parser = AppInfo.parse('u-u-i-d.mobileprovision')
|
53
54
|
parser = AppInfo.parse('macOS.App.zip')
|
54
55
|
parser = AppInfo.parse('App.dSYm.zip')
|
@@ -153,56 +154,67 @@ profile.enabled_capabilities
|
|
153
154
|
|
154
155
|
### Android
|
155
156
|
|
157
|
+
Accept `.aab` and `.apk` Android file.
|
158
|
+
|
156
159
|
```ruby
|
157
|
-
|
160
|
+
android = AppInfo.parse('android.apk_or_aab')
|
158
161
|
|
159
162
|
# get app file size
|
160
|
-
|
163
|
+
android.size
|
161
164
|
# => 3093823
|
162
165
|
|
163
166
|
# get app file size in human reable.
|
164
|
-
|
167
|
+
android.size(human_size: true)
|
165
168
|
# => 29 MB
|
166
169
|
|
167
170
|
# get app release version
|
168
|
-
|
171
|
+
android.release_version
|
169
172
|
# => 1.0
|
170
173
|
|
171
174
|
# get app package name
|
172
|
-
|
175
|
+
android.bundle_id
|
173
176
|
# => com.icyleaf.AppInfoDemo
|
174
177
|
|
178
|
+
# detect app type (It's difficult to detect phone or tablet)
|
179
|
+
android.tv?
|
180
|
+
android.wear?
|
181
|
+
android.automotive?
|
182
|
+
|
175
183
|
# get app icons
|
176
|
-
|
184
|
+
android.icons
|
177
185
|
# => [{:name=>"ic_launcher.png", :file=> "/temp/dir/app/ic_launcher.png", :dimensions=>[48, 48]}, ...]
|
178
186
|
|
179
187
|
# get app support min sdk version
|
180
|
-
|
188
|
+
android.min_sdk_version
|
181
189
|
# => 13
|
182
190
|
|
183
191
|
# get use_permissions list
|
184
|
-
|
192
|
+
android.use_permissions
|
185
193
|
# => [...]
|
186
194
|
|
187
195
|
# get activitiy list
|
188
|
-
|
196
|
+
android.activities
|
189
197
|
# => [...]
|
190
198
|
|
191
199
|
# get service list
|
192
|
-
|
200
|
+
android.services
|
193
201
|
# => [...]
|
194
202
|
|
195
|
-
# get
|
196
|
-
|
197
|
-
# => [
|
203
|
+
# get deep links host
|
204
|
+
android.deep_links
|
205
|
+
# => ['a.com']
|
198
206
|
|
199
|
-
# get
|
200
|
-
|
207
|
+
# get schemes without http or https
|
208
|
+
android.schemes
|
209
|
+
# => ['appinfo']
|
210
|
+
|
211
|
+
# get sign list (only v1 sign)
|
212
|
+
android.signs
|
201
213
|
# => [...]
|
202
214
|
|
203
|
-
#
|
204
|
-
|
205
|
-
|
215
|
+
# get certificate list (only v1 sign)
|
216
|
+
android.certificates
|
217
|
+
# => [...]
|
206
218
|
```
|
207
219
|
|
208
220
|
### macOS
|
@@ -296,9 +308,9 @@ It is possible to use this gem as a command line interface to parse mobile app:
|
|
296
308
|
```
|
297
309
|
> app-info
|
298
310
|
|
299
|
-
app-info (
|
311
|
+
app-info (2.7.0)> p = AppInfo.parse('/path/to/app')
|
300
312
|
=> #<AppInfo::APK::......>
|
301
|
-
app-info (
|
313
|
+
app-info (2.7.0)> p.name
|
302
314
|
=> "AppName"
|
303
315
|
```
|
304
316
|
|
data/Rakefile
CHANGED
data/app_info.gemspec
CHANGED
@@ -21,13 +21,13 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.required_ruby_version = '>= 2.5'
|
22
22
|
|
23
23
|
spec.add_dependency 'CFPropertyList', '< 3.1.0', '>= 2.3.4'
|
24
|
-
spec.add_dependency 'image_size', '>= 1.5', '<
|
24
|
+
spec.add_dependency 'image_size', '>= 1.5', '< 3.1'
|
25
25
|
spec.add_dependency 'ruby-macho', '< 3', '>= 1.4'
|
26
|
-
spec.add_dependency 'android_parser', '~> 2.
|
26
|
+
spec.add_dependency 'android_parser', '~> 2.5.0'
|
27
27
|
spec.add_dependency 'rubyzip', '>= 1.2', '< 3.0'
|
28
28
|
spec.add_dependency 'uuidtools', '>= 2.1.5', '< 2.3.0'
|
29
29
|
spec.add_dependency 'icns', '~> 0.2.0'
|
30
|
-
spec.add_dependency 'google-protobuf', '~> 3.
|
30
|
+
spec.add_dependency 'google-protobuf', '~> 3.19.2'
|
31
31
|
|
32
32
|
spec.add_development_dependency 'bundler', '>= 1.12'
|
33
33
|
spec.add_development_dependency 'rake', '>= 10.0'
|
data/lib/app_info/aab.rb
CHANGED
@@ -14,10 +14,11 @@ module AppInfo
|
|
14
14
|
|
15
15
|
# APK Devices
|
16
16
|
module Device
|
17
|
-
PHONE
|
18
|
-
TABLET
|
19
|
-
WATCH
|
20
|
-
TV
|
17
|
+
PHONE = 'Phone'
|
18
|
+
TABLET = 'Tablet'
|
19
|
+
WATCH = 'Watch'
|
20
|
+
TV = 'Television'
|
21
|
+
AUTOMOTIVE = 'Automotive'
|
21
22
|
end
|
22
23
|
|
23
24
|
BASE_PATH = 'base'
|
@@ -37,7 +38,7 @@ module AppInfo
|
|
37
38
|
end
|
38
39
|
alias file_type os
|
39
40
|
|
40
|
-
def_delegators :manifest, :version_name
|
41
|
+
def_delegators :manifest, :version_name, :deep_links, :schemes
|
41
42
|
|
42
43
|
alias release_version version_name
|
43
44
|
|
@@ -61,6 +62,8 @@ module AppInfo
|
|
61
62
|
Device::WATCH
|
62
63
|
elsif tv?
|
63
64
|
Device::TV
|
65
|
+
elsif automotive?
|
66
|
+
Device::AUTOMOTIVE
|
64
67
|
else
|
65
68
|
Device::PHONE
|
66
69
|
end
|
@@ -83,6 +86,10 @@ module AppInfo
|
|
83
86
|
use_features.include?('android.software.leanback')
|
84
87
|
end
|
85
88
|
|
89
|
+
def automotive?
|
90
|
+
use_features.include?('android.hardware.type.automotive')
|
91
|
+
end
|
92
|
+
|
86
93
|
def min_sdk_version
|
87
94
|
manifest.uses_sdk.min_sdk_version
|
88
95
|
end
|
@@ -112,6 +119,18 @@ module AppInfo
|
|
112
119
|
@components ||= manifest.components.transform_values
|
113
120
|
end
|
114
121
|
|
122
|
+
def sign_version
|
123
|
+
return 'v1' unless signs.empty?
|
124
|
+
|
125
|
+
# when ?
|
126
|
+
# https://source.android.com/security/apksigning/v2?hl=zh-cn
|
127
|
+
# 'v2'
|
128
|
+
# when ?
|
129
|
+
# https://source.android.com/security/apksigning/v3?hl=zh-cn
|
130
|
+
# 'v3'
|
131
|
+
'unknown'
|
132
|
+
end
|
133
|
+
|
115
134
|
def signs
|
116
135
|
return @signs if @signs
|
117
136
|
|
data/lib/app_info/apk.rb
CHANGED
@@ -14,10 +14,11 @@ module AppInfo
|
|
14
14
|
|
15
15
|
# APK Devices
|
16
16
|
module Device
|
17
|
-
PHONE
|
18
|
-
TABLET
|
19
|
-
WATCH
|
20
|
-
TV
|
17
|
+
PHONE = 'Phone'
|
18
|
+
TABLET = 'Tablet'
|
19
|
+
WATCH = 'Watch'
|
20
|
+
TV = 'Television'
|
21
|
+
AUTOMOTIVE = 'Automotive'
|
21
22
|
end
|
22
23
|
|
23
24
|
def initialize(file)
|
@@ -35,8 +36,9 @@ module AppInfo
|
|
35
36
|
|
36
37
|
def_delegators :apk, :manifest, :resource, :dex
|
37
38
|
|
38
|
-
def_delegators :manifest, :version_name, :package_name,
|
39
|
-
:use_permissions, :
|
39
|
+
def_delegators :manifest, :version_name, :package_name, :target_sdk_version,
|
40
|
+
:components, :services, :use_permissions, :use_features,
|
41
|
+
:deep_links, :schemes
|
40
42
|
|
41
43
|
alias release_version version_name
|
42
44
|
alias identifier package_name
|
@@ -56,14 +58,15 @@ module AppInfo
|
|
56
58
|
Device::WATCH
|
57
59
|
elsif tv?
|
58
60
|
Device::TV
|
61
|
+
elsif automotive?
|
62
|
+
Device::AUTOMOTIVE
|
59
63
|
else
|
60
64
|
Device::PHONE
|
61
65
|
end
|
62
66
|
end
|
63
67
|
|
64
|
-
# TODO: find a way to detect
|
68
|
+
# TODO: find a way to detect, no way!
|
65
69
|
# def tablet?
|
66
|
-
# resource
|
67
70
|
# end
|
68
71
|
|
69
72
|
def wear?
|
@@ -74,20 +77,25 @@ module AppInfo
|
|
74
77
|
use_features.include?('android.software.leanback')
|
75
78
|
end
|
76
79
|
|
80
|
+
def automotive?
|
81
|
+
use_features.include?('android.hardware.type.automotive')
|
82
|
+
end
|
83
|
+
|
77
84
|
def min_sdk_version
|
78
85
|
manifest.min_sdk_ver
|
79
86
|
end
|
80
87
|
alias min_os_version min_sdk_version
|
81
88
|
|
82
|
-
def
|
83
|
-
|
84
|
-
.elements['/manifest/uses-sdk']
|
85
|
-
.attributes['targetSdkVersion']
|
86
|
-
.to_i
|
87
|
-
end
|
89
|
+
def sign_version
|
90
|
+
return 'v1' unless signs.empty?
|
88
91
|
|
89
|
-
|
90
|
-
|
92
|
+
# when ?
|
93
|
+
# https://source.android.com/security/apksigning/v2?hl=zh-cn
|
94
|
+
# 'v2'
|
95
|
+
# when ?
|
96
|
+
# https://source.android.com/security/apksigning/v3?hl=zh-cn
|
97
|
+
# 'v3'
|
98
|
+
'unknown'
|
91
99
|
end
|
92
100
|
|
93
101
|
def signs
|
@@ -106,10 +114,6 @@ module AppInfo
|
|
106
114
|
components.select { |c| c.type == 'activity' }
|
107
115
|
end
|
108
116
|
|
109
|
-
def services
|
110
|
-
components.select { |c| c.type == 'service' }
|
111
|
-
end
|
112
|
-
|
113
117
|
def apk
|
114
118
|
@apk ||= ::Android::Apk.new(@file)
|
115
119
|
end
|
@@ -146,16 +150,6 @@ module AppInfo
|
|
146
150
|
@contents ||= File.join(Dir.mktmpdir, "AppInfo-android-#{SecureRandom.hex}")
|
147
151
|
end
|
148
152
|
|
149
|
-
private
|
150
|
-
|
151
|
-
def manifest_values(path, key = 'name')
|
152
|
-
values = []
|
153
|
-
manifest.doc.each_element(path) do |elem|
|
154
|
-
values << elem.attributes[key]
|
155
|
-
end
|
156
|
-
values.uniq
|
157
|
-
end
|
158
|
-
|
159
153
|
# Android Certificate
|
160
154
|
class Certificate
|
161
155
|
attr_reader :path, :certificate
|
@@ -129,19 +129,98 @@ module AppInfo
|
|
129
129
|
end
|
130
130
|
|
131
131
|
def activities
|
132
|
-
application.activity
|
132
|
+
application.respond_to?(:activity) ? application.activity : []
|
133
133
|
end
|
134
134
|
|
135
135
|
def services
|
136
|
-
application.service
|
136
|
+
application.respond_to?(:service) ? application.service : []
|
137
137
|
end
|
138
138
|
|
139
139
|
def icons
|
140
140
|
@resources.find(application.icon)
|
141
141
|
end
|
142
142
|
|
143
|
+
def deep_links
|
144
|
+
intent_filters(search: :deep_links)
|
145
|
+
end
|
146
|
+
|
147
|
+
def schemes
|
148
|
+
intent_filters(search: :schemes)
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def intent_filters(search: nil)
|
154
|
+
activities.each_with_object([]) do |activity, obj|
|
155
|
+
intent_filters = activity.intent_filter
|
156
|
+
next if intent_filters&.empty?
|
157
|
+
|
158
|
+
if search.nil? || search.empty?
|
159
|
+
obj << intent_filters
|
160
|
+
else
|
161
|
+
intent_filters.each do |filter|
|
162
|
+
exist_method = "#{search}?".to_sym
|
163
|
+
next if filter.respond_to?(exist_method) && !filter.send(exist_method)
|
164
|
+
|
165
|
+
obj << filter.send(search)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end.flatten.uniq
|
169
|
+
end
|
170
|
+
|
171
|
+
# :nodoc:
|
143
172
|
# Workaround ruby always return true by called `Object.const_defined?(Data)`
|
144
173
|
class Data < Node; end
|
174
|
+
|
175
|
+
class IntentFilter < Node
|
176
|
+
# filter types (action is required, category and data are optional)
|
177
|
+
TYPES = %w[action category data].freeze
|
178
|
+
|
179
|
+
DEEP_LINK_SCHEMES = %w[http https].freeze
|
180
|
+
|
181
|
+
# browsable of category
|
182
|
+
CATEGORY_BROWSABLE = 'android.intent.category.BROWSABLE'
|
183
|
+
|
184
|
+
def deep_links?
|
185
|
+
browsable? && data.any? { |d| DEEP_LINK_SCHEMES.include?(d.scheme) }
|
186
|
+
end
|
187
|
+
|
188
|
+
def deep_links
|
189
|
+
return unless deep_links?
|
190
|
+
|
191
|
+
data.reject { |d| d.host.nil? }
|
192
|
+
.map(&:host)
|
193
|
+
.uniq
|
194
|
+
end
|
195
|
+
|
196
|
+
def schemes
|
197
|
+
return unless schemes?
|
198
|
+
|
199
|
+
data.select { |d| !d.scheme.nil? && !DEEP_LINK_SCHEMES.include?(d.scheme) }
|
200
|
+
.map(&:scheme)
|
201
|
+
.uniq
|
202
|
+
end
|
203
|
+
|
204
|
+
def schemes?
|
205
|
+
browsable? && data.any? { |d| !DEEP_LINK_SCHEMES.include?(d.scheme) }
|
206
|
+
end
|
207
|
+
|
208
|
+
def browsable?
|
209
|
+
exist?(CATEGORY_BROWSABLE)
|
210
|
+
end
|
211
|
+
|
212
|
+
def exist?(name, type: nil)
|
213
|
+
if type.to_s.empty? && !name.start_with?('android.intent.')
|
214
|
+
raise 'Fill type or use correct name'
|
215
|
+
end
|
216
|
+
|
217
|
+
type ||= name.split('.')[2]
|
218
|
+
raise 'Not found type' unless TYPES.include?(type)
|
219
|
+
|
220
|
+
values = send(type.to_sym).select { |e| e.name == name }
|
221
|
+
values.empty? ? false : values
|
222
|
+
end
|
223
|
+
end
|
145
224
|
end
|
146
225
|
end
|
147
226
|
end
|
data/lib/app_info/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: app-info
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.2.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- icyleaf
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: CFPropertyList
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
version: '1.5'
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
42
|
+
version: '3.1'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -49,7 +49,7 @@ dependencies:
|
|
49
49
|
version: '1.5'
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: '
|
52
|
+
version: '3.1'
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: ruby-macho
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -76,14 +76,14 @@ dependencies:
|
|
76
76
|
requirements:
|
77
77
|
- - "~>"
|
78
78
|
- !ruby/object:Gem::Version
|
79
|
-
version: 2.
|
79
|
+
version: 2.5.0
|
80
80
|
type: :runtime
|
81
81
|
prerelease: false
|
82
82
|
version_requirements: !ruby/object:Gem::Requirement
|
83
83
|
requirements:
|
84
84
|
- - "~>"
|
85
85
|
- !ruby/object:Gem::Version
|
86
|
-
version: 2.
|
86
|
+
version: 2.5.0
|
87
87
|
- !ruby/object:Gem::Dependency
|
88
88
|
name: rubyzip
|
89
89
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,14 +144,14 @@ dependencies:
|
|
144
144
|
requirements:
|
145
145
|
- - "~>"
|
146
146
|
- !ruby/object:Gem::Version
|
147
|
-
version: 3.
|
147
|
+
version: 3.19.2
|
148
148
|
type: :runtime
|
149
149
|
prerelease: false
|
150
150
|
version_requirements: !ruby/object:Gem::Requirement
|
151
151
|
requirements:
|
152
152
|
- - "~>"
|
153
153
|
- !ruby/object:Gem::Version
|
154
|
-
version: 3.
|
154
|
+
version: 3.19.2
|
155
155
|
- !ruby/object:Gem::Dependency
|
156
156
|
name: bundler
|
157
157
|
requirement: !ruby/object:Gem::Requirement
|
@@ -276,7 +276,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
276
276
|
- !ruby/object:Gem::Version
|
277
277
|
version: 1.3.1
|
278
278
|
requirements: []
|
279
|
-
rubygems_version: 3.
|
279
|
+
rubygems_version: 3.2.3
|
280
280
|
signing_key:
|
281
281
|
specification_version: 4
|
282
282
|
summary: Teardown tool for mobile app(ipa/apk) and dSYM file, analysis metedata like
|