ruboto 1.4.1 → 1.5.0
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/CONTRIBUTING.md +28 -0
- data/Gemfile.lock +12 -10
- data/README.md +3 -24
- data/RELEASE_CANDICATE_DOC.md +4 -3
- data/RELEASE_DOC.md +38 -23
- data/Rakefile +18 -18
- data/Vagrantfile +1 -0
- data/assets/rakelib/ruboto.device.rb +25 -18
- data/assets/rakelib/ruboto.rake +18 -8
- data/assets/rakelib/ruboto.stdlib.rake +26 -2
- data/assets/ruboto.yml +32 -2
- data/assets/src/org/jruby/ext/openssl/OpenSSL.java +320 -0
- data/assets/src/ruboto/util/stack.rb +2 -0
- data/lib/ruboto/util/emulator.rb +54 -32
- data/lib/ruboto/util/setup.rb +21 -23
- data/lib/ruboto/util/update.rb +18 -32
- data/lib/ruboto/version.rb +1 -1
- data/test/app_test_methods.rb +23 -15
- data/test/arjdbc_test.rb +1 -1
- data/test/rake_test.rb +22 -12
- data/test/ruboto_setup_test.rb +2 -7
- data/test/test_helper.rb +4 -3
- metadata +23 -5
@@ -181,6 +181,12 @@ def remove_unneeded_parts_of_stdlib
|
|
181
181
|
end
|
182
182
|
end
|
183
183
|
|
184
|
+
def add_fake_jar(source_file, jar_load_code)
|
185
|
+
File.write(source_file, jar_load_code)
|
186
|
+
open("#{File.dirname(source_file)}/.jrubydir", 'a') { |f| f.puts File.basename source_file }
|
187
|
+
end
|
188
|
+
private :add_fake_jar
|
189
|
+
|
184
190
|
def cleanup_jars
|
185
191
|
Dir.chdir 'new' do
|
186
192
|
cmd_line_jar_found = false
|
@@ -224,6 +230,7 @@ def cleanup_jars
|
|
224
230
|
print "#{File.basename(j).chomp('.jar')}..."
|
225
231
|
system "jar xf #{j}"
|
226
232
|
FileUtils.rm j
|
233
|
+
|
227
234
|
if ENV['STRIP_INVOKERS']
|
228
235
|
invokers = Dir['**/*$INVOKER$*.class']
|
229
236
|
if invokers.size > 0
|
@@ -252,6 +259,22 @@ def cleanup_jars
|
|
252
259
|
Java::json.ext.ParserService.new.basicLoad(JRuby.runtime)
|
253
260
|
END_CODE
|
254
261
|
elsif j =~ %r{jopenssl.jar$}
|
262
|
+
# FIXME(uwe): Use our own patched version of OpenSSL until jruby-openssl 0.9.16 is released
|
263
|
+
# FIXME(uwe): Remove before Ruboto release!
|
264
|
+
# FIXME(uwe): Remove after jruby-openssl 0.9.16 is added to the jruby-1_7 branch
|
265
|
+
if File.exists? 'org/jruby/ext/openssl/OpenSSL.class'
|
266
|
+
puts '*' * 80
|
267
|
+
puts 'Patching OpenSSL'
|
268
|
+
FileUtils.rm 'org/jruby/ext/openssl/OpenSSL.class'
|
269
|
+
FileUtils.mkdir_p '../../../src/org/jruby/ext/openssl'
|
270
|
+
# require 'ruboto'
|
271
|
+
# FileUtils.cp "#{Ruboto::ASSETS}/src/org/jruby/ext/openssl/OpenSSL.java",
|
272
|
+
# '../../../src/org/jruby/ext/openssl/OpenSSL.java'
|
273
|
+
FileUtils.cp File.expand_path('../../../assets/src/org/jruby/ext/openssl/OpenSSL.java', File.dirname(__FILE__)),
|
274
|
+
'../../../src/org/jruby/ext/openssl/OpenSSL.java'
|
275
|
+
puts '*' * 80
|
276
|
+
end
|
277
|
+
# EMXIF
|
255
278
|
jar_load_code = <<-END_CODE
|
256
279
|
require 'jruby'
|
257
280
|
puts 'Starting JOpenSSL Service'
|
@@ -279,10 +302,11 @@ def cleanup_jars
|
|
279
302
|
END_CODE
|
280
303
|
else
|
281
304
|
jar_load_code = ''
|
305
|
+
add_fake_jar("#{j}", jar_load_code)
|
282
306
|
end
|
283
307
|
|
284
|
-
|
285
|
-
|
308
|
+
add_fake_jar("#{j}.rb", jar_load_code)
|
309
|
+
# add_fake_jar("#{j}.jar.rb", jar_load_code)
|
286
310
|
end
|
287
311
|
unless cmd_line_jar_found
|
288
312
|
puts "\nWARNING: No command line jar filtered. Has it changed?"
|
data/assets/ruboto.yml
CHANGED
@@ -1,10 +1,40 @@
|
|
1
|
+
###################################
|
2
|
+
#
|
3
|
+
# emulator:
|
4
|
+
#
|
5
|
+
# Specifies which emulator to use when running `ruboto emulator`.
|
6
|
+
#
|
7
|
+
# Name of the AVD to be used. It will be created if not already present.
|
8
|
+
# default: "Android_#{android_version}"
|
9
|
+
#
|
10
|
+
# name: Android_4.0.3_tablet
|
11
|
+
#
|
12
|
+
# Name of the Android device to be used as template. Setting this options
|
13
|
+
# disables the "skin" option on AVD creation and starts the emulator without
|
14
|
+
# the "-no-skin" option.
|
15
|
+
# default: Nexus One
|
16
|
+
#
|
17
|
+
# device: Nexus 10
|
18
|
+
#
|
19
|
+
# Name of the Android emulator skin to use when creating the AVD.
|
20
|
+
# default: HVGA
|
21
|
+
#
|
22
|
+
# skin: HVGA
|
23
|
+
#
|
24
|
+
# Example:
|
25
|
+
#
|
26
|
+
# emulator:
|
27
|
+
# name: Android_4.0.3_tablet # default: "Android_#{android_version}"
|
28
|
+
# device: Nexus 10 # default: Nexus One
|
29
|
+
# skin: HVGA # default: HVGA
|
30
|
+
|
1
31
|
###################################
|
2
32
|
#
|
3
33
|
# heap_alloc
|
4
|
-
#
|
34
|
+
#
|
5
35
|
# Forces the heap to grow by a number of megabytes.
|
6
36
|
# Can result in improved start-up performance because
|
7
|
-
# it prevents the heap from growing through smaller
|
37
|
+
# it prevents the heap from growing through smaller
|
8
38
|
# increments.
|
9
39
|
#
|
10
40
|
# heap_alloc: 13
|
@@ -0,0 +1,320 @@
|
|
1
|
+
/*
|
2
|
+
* The MIT License
|
3
|
+
*
|
4
|
+
* Copyright (c) 2014 Karol Bucek LTD.
|
5
|
+
*
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
11
|
+
* furnished to do so, subject to the following conditions:
|
12
|
+
*
|
13
|
+
* The above copyright notice and this permission notice shall be included in
|
14
|
+
* all copies or substantial portions of the Software.
|
15
|
+
*
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
* THE SOFTWARE.
|
23
|
+
*/
|
24
|
+
package org.jruby.ext.openssl;
|
25
|
+
|
26
|
+
import java.security.NoSuchProviderException;
|
27
|
+
import java.util.Map;
|
28
|
+
|
29
|
+
import org.jruby.CompatVersion;
|
30
|
+
import org.jruby.Ruby;
|
31
|
+
import org.jruby.RubyArray;
|
32
|
+
import org.jruby.RubyClass;
|
33
|
+
import org.jruby.RubyModule;
|
34
|
+
import org.jruby.RubyString;
|
35
|
+
import org.jruby.anno.JRubyMethod;
|
36
|
+
import org.jruby.anno.JRubyModule;
|
37
|
+
import org.jruby.runtime.ThreadContext;
|
38
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
39
|
+
import org.jruby.util.ByteList;
|
40
|
+
import org.jruby.util.SafePropertyAccessor;
|
41
|
+
|
42
|
+
/**
|
43
|
+
* OpenSSL (methods as well as an entry point)
|
44
|
+
*
|
45
|
+
* @author kares
|
46
|
+
*/
|
47
|
+
@JRubyModule(name = "OpenSSL")
|
48
|
+
public final class OpenSSL {
|
49
|
+
|
50
|
+
public static void load(final Ruby runtime) {
|
51
|
+
System.out.println("CUSTOM OpenSSL load");
|
52
|
+
createOpenSSL(runtime);
|
53
|
+
}
|
54
|
+
|
55
|
+
public static boolean isProviderAvailable() {
|
56
|
+
System.out.println("CUSTOM OpenSSL isProviderAvailable");
|
57
|
+
return SecurityHelper.isProviderAvailable("BC");
|
58
|
+
}
|
59
|
+
|
60
|
+
public static void createOpenSSL(final Ruby runtime) {
|
61
|
+
System.out.println("CUSTOM OpenSSL createOpenSSL");
|
62
|
+
boolean registerProvider = SafePropertyAccessor.getBoolean("jruby.openssl.provider.register");
|
63
|
+
SecurityHelper.setRegisterProvider( registerProvider );
|
64
|
+
|
65
|
+
System.out.println("OpenSSL createOpenSSL create module");
|
66
|
+
final RubyModule _OpenSSL = runtime.getOrCreateModule("OpenSSL");
|
67
|
+
System.out.println("OpenSSL createOpenSSL create OpenSSLError");
|
68
|
+
RubyClass _StandardError = runtime.getClass("StandardError");
|
69
|
+
_OpenSSL.defineClassUnder("OpenSSLError", _StandardError, _StandardError.getAllocator());
|
70
|
+
System.out.println("OpenSSL createOpenSSL defineAnnotatedMethods");
|
71
|
+
_OpenSSL.defineAnnotatedMethods(OpenSSL.class);
|
72
|
+
|
73
|
+
// set OpenSSL debug internal flag early on so it can print traces even while loading extension
|
74
|
+
System.out.println("OpenSSL createOpenSSL debug");
|
75
|
+
setDebug(_OpenSSL, runtime.newBoolean( SafePropertyAccessor.getBoolean("jruby.openssl.debug") ) );
|
76
|
+
|
77
|
+
System.out.println("OpenSSL createOpenSSL warn");
|
78
|
+
final String warn = SafePropertyAccessor.getProperty("jruby.openssl.warn");
|
79
|
+
if ( warn != null ) OpenSSL.warn = Boolean.parseBoolean(warn);
|
80
|
+
|
81
|
+
System.out.println("OpenSSL createOpenSSL createPKey");
|
82
|
+
PKey.createPKey(runtime, _OpenSSL);
|
83
|
+
System.out.println("OpenSSL createOpenSSL createBN");
|
84
|
+
BN.createBN(runtime, _OpenSSL);
|
85
|
+
System.out.println("OpenSSL createOpenSSL createDigest");
|
86
|
+
Digest.createDigest(runtime, _OpenSSL);
|
87
|
+
System.out.println("OpenSSL createOpenSSL createCipher");
|
88
|
+
Cipher.createCipher(runtime, _OpenSSL);
|
89
|
+
System.out.println("OpenSSL createOpenSSL createRandom");
|
90
|
+
Random.createRandom(runtime, _OpenSSL);
|
91
|
+
System.out.println("OpenSSL createOpenSSL createHMAC");
|
92
|
+
HMAC.createHMAC(runtime, _OpenSSL);
|
93
|
+
System.out.println("OpenSSL createOpenSSL createConfig");
|
94
|
+
Config.createConfig(runtime, _OpenSSL);
|
95
|
+
System.out.println("OpenSSL createOpenSSL createASN1");
|
96
|
+
ASN1.createASN1(runtime, _OpenSSL);
|
97
|
+
System.out.println("OpenSSL createOpenSSL createX509");
|
98
|
+
X509.createX509(runtime, _OpenSSL);
|
99
|
+
System.out.println("OpenSSL createOpenSSL createNetscapeSPKI");
|
100
|
+
NetscapeSPKI.createNetscapeSPKI(runtime, _OpenSSL);
|
101
|
+
try {
|
102
|
+
System.out.println("OpenSSL createOpenSSL createSSL");
|
103
|
+
SSL.createSSL(runtime, _OpenSSL);
|
104
|
+
} catch (Throwable e) {
|
105
|
+
System.out.println("Got exception creating SSL:");
|
106
|
+
e.printStackTrace();
|
107
|
+
}
|
108
|
+
System.out.println("OpenSSL createOpenSSL createPKCS7");
|
109
|
+
PKCS7.createPKCS7(runtime, _OpenSSL);
|
110
|
+
System.out.println("OpenSSL createOpenSSL createPKCS5");
|
111
|
+
PKCS5.createPKCS5(runtime, _OpenSSL);
|
112
|
+
|
113
|
+
System.out.println("OpenSSL createOpenSSL require version");
|
114
|
+
runtime.getLoadService().require("jopenssl/version");
|
115
|
+
|
116
|
+
// MRI 1.8.7 :
|
117
|
+
// OpenSSL::VERSION: "1.0.0"
|
118
|
+
// OpenSSL::OPENSSL_VERSION: "OpenSSL 1.0.1c 10 May 2012"
|
119
|
+
// OpenSSL::OPENSSL_VERSION_NUMBER: 268439615
|
120
|
+
// MRI 1.9.3 / 2.2.3 :
|
121
|
+
// OpenSSL::VERSION: "1.1.0"
|
122
|
+
// OpenSSL::OPENSSL_VERSION: "OpenSSL 1.0.1f 6 Jan 2014"
|
123
|
+
// OpenSSL::OPENSSL_VERSION_NUMBER: 268439663
|
124
|
+
// OpenSSL::OPENSSL_LIBRARY_VERSION: ""OpenSSL 1.0.2d 9 Jul 2015"
|
125
|
+
// OpenSSL::FIPS: false
|
126
|
+
|
127
|
+
System.out.println("OpenSSL createOpenSSL check version");
|
128
|
+
final byte[] version = { '1','.','1','.','0' };
|
129
|
+
final boolean ruby18 = runtime.getInstanceConfig().getCompatVersion() == CompatVersion.RUBY1_8;
|
130
|
+
if ( ruby18 ) version[2] = '0'; // 1.0.0 compatible on 1.8
|
131
|
+
|
132
|
+
System.out.println("OpenSSL createOpenSSL set version");
|
133
|
+
_OpenSSL.setConstant("VERSION", StringHelper.newString(runtime, version));
|
134
|
+
|
135
|
+
System.out.println("OpenSSL createOpenSSL get Jopenssl version");
|
136
|
+
final RubyModule _Jopenssl = runtime.getModule("Jopenssl");
|
137
|
+
final RubyModule _Version = (RubyModule) _Jopenssl.getConstantAt("Version");
|
138
|
+
final RubyString jVERSION = _Version.getConstantAt("VERSION").asString();
|
139
|
+
|
140
|
+
final byte[] JRuby_OpenSSL_ = { 'J','R','u','b','y','-','O','p','e','n','S','S','L',' ' };
|
141
|
+
final int OPENSSL_VERSION_NUMBER = 999999999; // NOTE: smt more useful?
|
142
|
+
|
143
|
+
ByteList OPENSSL_VERSION = new ByteList( jVERSION.getByteList().length() + JRuby_OpenSSL_.length );
|
144
|
+
OPENSSL_VERSION.setEncoding( jVERSION.getEncoding() );
|
145
|
+
OPENSSL_VERSION.append( JRuby_OpenSSL_ );
|
146
|
+
OPENSSL_VERSION.append( jVERSION.getByteList() );
|
147
|
+
|
148
|
+
final RubyString VERSION;
|
149
|
+
_OpenSSL.setConstant("OPENSSL_VERSION", VERSION = runtime.newString(OPENSSL_VERSION));
|
150
|
+
_OpenSSL.setConstant("OPENSSL_VERSION_NUMBER", runtime.newFixnum(OPENSSL_VERSION_NUMBER));
|
151
|
+
if ( ! ruby18 ) {
|
152
|
+
// MRI 2.3 tests do: /\AOpenSSL +0\./ !~ OpenSSL::OPENSSL_LIBRARY_VERSION
|
153
|
+
_OpenSSL.setConstant("OPENSSL_LIBRARY_VERSION", VERSION);
|
154
|
+
_OpenSSL.setConstant("OPENSSL_FIPS", runtime.getFalse());
|
155
|
+
}
|
156
|
+
System.out.println("OpenSSL createOpenSSL...OK");
|
157
|
+
}
|
158
|
+
|
159
|
+
static RubyClass _OpenSSLError(final Ruby runtime) {
|
160
|
+
return runtime.getModule("OpenSSL").getClass("OpenSSLError");
|
161
|
+
}
|
162
|
+
|
163
|
+
// OpenSSL module methods :
|
164
|
+
|
165
|
+
@JRubyMethod(name = "errors", meta = true)
|
166
|
+
public static IRubyObject errors(IRubyObject self) {
|
167
|
+
final Ruby runtime = self.getRuntime();
|
168
|
+
RubyArray result = runtime.newArray();
|
169
|
+
for (Map.Entry<Integer, String> e : X509.getErrors().entrySet()) {
|
170
|
+
result.add( runtime.newString( e.getValue() ) );
|
171
|
+
}
|
172
|
+
return result;
|
173
|
+
}
|
174
|
+
|
175
|
+
@JRubyMethod(name = "debug", meta = true)
|
176
|
+
public static IRubyObject getDebug(IRubyObject self) {
|
177
|
+
return (IRubyObject) getDebug((RubyModule) self);
|
178
|
+
}
|
179
|
+
|
180
|
+
private static Object getDebug(RubyModule self) {
|
181
|
+
return self.getInternalVariable("debug");
|
182
|
+
}
|
183
|
+
|
184
|
+
@JRubyMethod(name = "debug=", meta = true)
|
185
|
+
public static IRubyObject setDebug(IRubyObject self, IRubyObject debug) {
|
186
|
+
((RubyModule) self).setInternalVariable("debug", debug);
|
187
|
+
OpenSSL.debug = debug.isTrue();
|
188
|
+
return debug;
|
189
|
+
}
|
190
|
+
|
191
|
+
@JRubyMethod(name = "Digest", meta = true)
|
192
|
+
public static IRubyObject Digest(final IRubyObject self, final IRubyObject name) {
|
193
|
+
// OpenSSL::Digest("MD5") -> OpenSSL::Digest::MD5
|
194
|
+
final Ruby runtime = self.getRuntime();
|
195
|
+
final RubyClass Digest = runtime.getModule("OpenSSL").getClass("Digest");
|
196
|
+
return Digest.getConstantAt( name.asString().toString() );
|
197
|
+
}
|
198
|
+
|
199
|
+
// API "stubs" in JRuby-OpenSSL :
|
200
|
+
|
201
|
+
@JRubyMethod(meta = true)
|
202
|
+
public static IRubyObject deprecated_warning_flag(final IRubyObject self) {
|
203
|
+
return self.getRuntime().getNil(); // no-op in JRuby-OpenSSL
|
204
|
+
}
|
205
|
+
|
206
|
+
@JRubyMethod(meta = true, rest = true) // check_func(func, header)
|
207
|
+
public static IRubyObject check_func(final IRubyObject self, final IRubyObject[] args) {
|
208
|
+
return self.getRuntime().getNil(); // no-op in JRuby-OpenSSL
|
209
|
+
}
|
210
|
+
|
211
|
+
// Added in 2.0; not masked because it does nothing anyway (there's no reader in MRI)
|
212
|
+
@JRubyMethod(name = "fips_mode=", meta = true)
|
213
|
+
public static IRubyObject set_fips_mode(ThreadContext context, IRubyObject self, IRubyObject value) {
|
214
|
+
if ( value.isTrue() ) {
|
215
|
+
warn(context, "WARNING: FIPS mode not supported on JRuby-OpenSSL");
|
216
|
+
}
|
217
|
+
return value;
|
218
|
+
}
|
219
|
+
|
220
|
+
// internal (package-level) helpers :
|
221
|
+
|
222
|
+
private static boolean debug;
|
223
|
+
|
224
|
+
// on by default, warnings can be disabled using -Djruby.openssl.warn=false
|
225
|
+
private static boolean warn = true;
|
226
|
+
|
227
|
+
static boolean isDebug() { return debug; }
|
228
|
+
|
229
|
+
static void debugStackTrace(final Throwable e) {
|
230
|
+
if ( isDebug() ) e.printStackTrace(System.out);
|
231
|
+
}
|
232
|
+
|
233
|
+
static void debug(final String msg) {
|
234
|
+
if ( isDebug() ) System.out.println(msg);
|
235
|
+
}
|
236
|
+
|
237
|
+
static void debug(final String msg, final Throwable e) {
|
238
|
+
if ( isDebug() ) System.out.println(msg + ' ' + e);
|
239
|
+
}
|
240
|
+
|
241
|
+
static boolean isDebug(final Ruby runtime) {
|
242
|
+
final RubyModule OpenSSL = runtime.getModule("OpenSSL");
|
243
|
+
if ( OpenSSL == null ) return debug; // debug early on
|
244
|
+
return getDebug( OpenSSL ) == runtime.getTrue();
|
245
|
+
}
|
246
|
+
|
247
|
+
static void debugStackTrace(final Ruby runtime, final Throwable e) {
|
248
|
+
if ( isDebug(runtime) ) e.printStackTrace(runtime.getOut());
|
249
|
+
}
|
250
|
+
|
251
|
+
static void debug(final Ruby runtime, final String msg) {
|
252
|
+
if ( isDebug(runtime) ) runtime.getOut().println(msg);
|
253
|
+
}
|
254
|
+
|
255
|
+
static void debug(final Ruby runtime, final String msg, final Throwable e) {
|
256
|
+
if ( isDebug(runtime) ) runtime.getOut().println(msg + ' ' + e);
|
257
|
+
}
|
258
|
+
|
259
|
+
static void warn(final ThreadContext context, final String msg) {
|
260
|
+
warn(context, RubyString.newString(context.runtime, msg));
|
261
|
+
}
|
262
|
+
|
263
|
+
static void warn(final ThreadContext context, final IRubyObject msg) {
|
264
|
+
if ( warn ) context.runtime.getModule("OpenSSL").callMethod(context, "warn", msg);
|
265
|
+
}
|
266
|
+
|
267
|
+
private static String javaVersion(final String def) {
|
268
|
+
final String javaVersionProperty =
|
269
|
+
SafePropertyAccessor.getProperty("java.version", def);
|
270
|
+
if (javaVersionProperty == "0") { // Android
|
271
|
+
return "1.7.0";
|
272
|
+
} else {
|
273
|
+
return javaVersionProperty;
|
274
|
+
}
|
275
|
+
}
|
276
|
+
|
277
|
+
static boolean javaVersion7(final boolean atLeast) {
|
278
|
+
final int gt = "1.7".compareTo( javaVersion("0.0").substring(0, 3) );
|
279
|
+
return atLeast ? gt <= 0 : gt == 0;
|
280
|
+
}
|
281
|
+
|
282
|
+
static boolean javaVersion8(final boolean atLeast) {
|
283
|
+
final int gt = "1.8".compareTo( javaVersion("0.0").substring(0, 3) );
|
284
|
+
return atLeast ? gt <= 0 : gt == 0;
|
285
|
+
}
|
286
|
+
|
287
|
+
private static String javaName(final String def) {
|
288
|
+
// Sun Java 6 or Oracle Java 7/8
|
289
|
+
// "Java HotSpot(TM) Server VM" or "Java HotSpot(TM) 64-Bit Server VM"
|
290
|
+
// OpenJDK :
|
291
|
+
// "OpenJDK 64-Bit Server VM"
|
292
|
+
return SafePropertyAccessor.getProperty("java.vm.name", def);
|
293
|
+
}
|
294
|
+
|
295
|
+
static boolean javaHotSpot() {
|
296
|
+
return javaName("").contains("HotSpot(TM)");
|
297
|
+
}
|
298
|
+
|
299
|
+
static boolean javaOpenJDK() {
|
300
|
+
return javaName("").contains("OpenJDK");
|
301
|
+
}
|
302
|
+
|
303
|
+
//
|
304
|
+
|
305
|
+
static IRubyObject to_der_if_possible(final ThreadContext context, IRubyObject obj) {
|
306
|
+
if ( ! obj.respondsTo("to_der")) return obj;
|
307
|
+
return obj.callMethod(context, "to_der");
|
308
|
+
}
|
309
|
+
|
310
|
+
//
|
311
|
+
|
312
|
+
static String bcExceptionMessage(NoSuchProviderException ex) {
|
313
|
+
return "You need to configure JVM/classpath to enable BouncyCastle Security Provider: " + ex;
|
314
|
+
}
|
315
|
+
|
316
|
+
static String bcExceptionMessage(NoClassDefFoundError ex) {
|
317
|
+
return "You need to configure JVM/classpath to enable BouncyCastle Security Provider: " + ex;
|
318
|
+
}
|
319
|
+
|
320
|
+
}
|
@@ -10,6 +10,7 @@
|
|
10
10
|
class Object
|
11
11
|
def with_large_stack(opts = {}, &block)
|
12
12
|
opts = {:size => opts} if opts.is_a? Integer
|
13
|
+
opts = {:name => opts} if opts.is_a? String
|
13
14
|
opts = {:name => 'Block with large stack'}.update(opts)
|
14
15
|
exception = nil
|
15
16
|
result = nil
|
@@ -23,6 +24,7 @@ end
|
|
23
24
|
class Thread
|
24
25
|
def self.with_large_stack(opts = {}, &block)
|
25
26
|
opts = {:size => opts} if opts.is_a? Integer
|
27
|
+
opts = {:name => opts} if opts.is_a? String
|
26
28
|
stack_size_kb = opts.delete(:size) || 64
|
27
29
|
name = opts.delete(:name) || 'Thread with large stack'
|
28
30
|
raise "Unknown option(s): #{opts.inspect}" unless opts.empty?
|
data/lib/ruboto/util/emulator.rb
CHANGED
@@ -5,6 +5,8 @@ require 'ruboto/sdk_locations'
|
|
5
5
|
module Ruboto
|
6
6
|
module Util
|
7
7
|
module Emulator
|
8
|
+
include Ruboto::Util::Verify
|
9
|
+
|
8
10
|
ON_WINDOWS = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw/i)
|
9
11
|
ON_MAC_OS_X = RbConfig::CONFIG['host_os'] =~ /^darwin/
|
10
12
|
ON_LINUX = RbConfig::CONFIG['host_os'] =~ /linux/
|
@@ -19,7 +21,7 @@ module Ruboto
|
|
19
21
|
STDOUT.sync = true
|
20
22
|
if RbConfig::CONFIG['host_cpu'] == 'x86_64'
|
21
23
|
if ON_MAC_OS_X
|
22
|
-
emulator_cmd = '-m "emulator64-(arm|x86)"'
|
24
|
+
emulator_cmd = '-m "emulator64-(crash-service|arm|x86)"'
|
23
25
|
elsif ON_LINUX
|
24
26
|
emulator_cmd = '-r "emulator64-(arm|x86)"'
|
25
27
|
else
|
@@ -29,7 +31,9 @@ module Ruboto
|
|
29
31
|
emulator_cmd = 'emulator-arm'
|
30
32
|
end
|
31
33
|
|
32
|
-
|
34
|
+
emulator_config = verify_ruboto_config['emulator']
|
35
|
+
avd_name = (emulator_config && emulator_config['name']) || "Android_#{sdk_level_name(sdk_level)}"
|
36
|
+
android_device = (emulator_config && emulator_config['device']) || "Nexus One"
|
33
37
|
new_snapshot = false
|
34
38
|
|
35
39
|
if `adb devices` =~ /emulator-5554/
|
@@ -57,8 +61,8 @@ module Ruboto
|
|
57
61
|
# FIXME(uwe): Change use of "killall" to use the Ruby Process API
|
58
62
|
loop do
|
59
63
|
emulator_opts = '-partition-size 256'
|
60
|
-
emulator_opts << ' -noskin'
|
61
|
-
emulator_opts << ' -no-snapshot
|
64
|
+
emulator_opts << ' -noskin' unless android_device
|
65
|
+
emulator_opts << ' -no-snapshot' if no_snapshot
|
62
66
|
if !ON_MAC_OS_X && !ON_WINDOWS && ENV['DISPLAY'].nil?
|
63
67
|
emulator_opts << ' -no-window -no-audio'
|
64
68
|
end
|
@@ -90,15 +94,13 @@ module Ruboto
|
|
90
94
|
avd_home = "#{ENV['HOME'].gsub('\\', '/')}/.android/avd/#{avd_name}.avd"
|
91
95
|
manifest_file = 'AndroidManifest.xml'
|
92
96
|
large_heap = (!File.exists?(manifest_file)) || (File.read(manifest_file) =~ /largeHeap/)
|
93
|
-
heap_size = large_heap ? 256 :
|
97
|
+
heap_size = large_heap ? 256 : 64
|
94
98
|
|
95
|
-
|
96
|
-
|
97
|
-
new_snapshot = true
|
99
|
+
if File.exists? avd_home
|
100
|
+
patch_config_ini(avd_home, heap_size, no_snapshot)
|
98
101
|
else
|
99
|
-
|
100
|
-
|
101
|
-
# EMXIF
|
102
|
+
create_avd(avd_home, avd_name, android_device, heap_size, sdk_level)
|
103
|
+
new_snapshot = true
|
102
104
|
end
|
103
105
|
|
104
106
|
puts "Start emulator #{avd_name}#{' without snapshot' if no_snapshot}"
|
@@ -121,7 +123,7 @@ module Ruboto
|
|
121
123
|
`killall -0 #{emulator_cmd} 2> /dev/null`
|
122
124
|
if $? != 0
|
123
125
|
puts 'Unable to start the emulator. Retrying without loading snapshot.'
|
124
|
-
system "emulator -no-snapshot
|
126
|
+
system "emulator -no-snapshot -avd #{avd_name} #{emulator_opts} #{'&' unless ON_WINDOWS}"
|
125
127
|
10.times do |i|
|
126
128
|
`killall -0 #{emulator_cmd} 2> /dev/null`
|
127
129
|
if $? == 0
|
@@ -191,7 +193,7 @@ EOF
|
|
191
193
|
puts "Emulator #{avd_name} started OK."
|
192
194
|
end
|
193
195
|
|
194
|
-
def create_avd(avd_home, avd_name, heap_size, sdk_level)
|
196
|
+
def create_avd(avd_home, avd_name, android_device, heap_size, sdk_level)
|
195
197
|
puts "Creating AVD #{avd_name}"
|
196
198
|
|
197
199
|
target = `android list target`.split(/----------\n/).
|
@@ -224,7 +226,12 @@ EOF
|
|
224
226
|
abi_opt = '--abi armeabi-v7a'
|
225
227
|
end
|
226
228
|
|
227
|
-
|
229
|
+
ruboto_config_filename = 'ruboto.yml'
|
230
|
+
if File.exists?(ruboto_config_filename)
|
231
|
+
ruboto_config = YAML.load_file(ruboto_config_filename)
|
232
|
+
skin = ruboto_config['emulator'] && ruboto_config['emulator']['skin']
|
233
|
+
end
|
234
|
+
skin ||= '768x1280'
|
228
235
|
# skin_filename = "#{Ruboto::SdkLocations::ANDROID_HOME}/platforms/android-#{sdk_level}/skins/#{skin}/hardware.ini"
|
229
236
|
# if File.exists?(skin_filename)
|
230
237
|
# old_skin_config = File.read(skin_filename)
|
@@ -234,7 +241,7 @@ EOF
|
|
234
241
|
# File.write(skin_filename, new_skin_config) if new_skin_config != old_skin_config
|
235
242
|
# end
|
236
243
|
|
237
|
-
puts `echo no | android create avd -a -n #{avd_name} -t android-#{sdk_level} #{abi_opt} -c 64M -s #{skin} -d "
|
244
|
+
puts `echo no | android create avd -a -n #{avd_name} -t android-#{sdk_level} #{abi_opt} -c 64M #{"-s #{skin}" if skin} -d "#{android_device}"`
|
238
245
|
|
239
246
|
if $? != 0
|
240
247
|
puts 'Failed to create AVD.'
|
@@ -242,25 +249,34 @@ EOF
|
|
242
249
|
end
|
243
250
|
patch_config_ini(avd_home, heap_size)
|
244
251
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
252
|
+
hw_config_file_name = "#{avd_home}/hardware-qemu.ini"
|
253
|
+
if File.exists?(hw_config_file_name)
|
254
|
+
old_hw_config = File.read(hw_config_file_name)
|
255
|
+
new_hw_config = old_hw_config.dup
|
256
|
+
update_heap_size(new_hw_config, heap_size)
|
257
|
+
File.write(hw_config_file_name, new_hw_config) if new_hw_config != old_hw_config
|
258
|
+
end
|
251
259
|
end
|
252
260
|
|
253
|
-
def
|
261
|
+
def update_heap_size(new_hw_config, heap_size)
|
262
|
+
old_heap = read_property(new_hw_config, 'vm.heapSize')
|
263
|
+
if old_heap.nil? || old_heap.to_i < heap_size
|
264
|
+
add_property(new_hw_config, 'vm.heapSize', heap_size)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def patch_config_ini(avd_home, heap_size, no_snapshot)
|
254
269
|
avd_config_file_name = "#{avd_home}/config.ini"
|
255
270
|
old_avd_config = File.read(avd_config_file_name)
|
256
271
|
new_avd_config = old_avd_config.dup
|
257
|
-
new_avd_config
|
272
|
+
update_heap_size(new_avd_config, heap_size)
|
258
273
|
# add_property(new_avd_config, 'hw.device.manufacturer', 'Generic')
|
259
274
|
# add_property(new_avd_config, 'hw.device.name', '3.2" HVGA slider (ADP1)')
|
260
275
|
# add_property(new_avd_config, 'hw.keyboard.lid', 'no')
|
261
|
-
add_property(new_avd_config, 'hw.lcd.density', '160')
|
276
|
+
# add_property(new_avd_config, 'hw.lcd.density', '160')
|
262
277
|
add_property(new_avd_config, 'hw.mainKeys', 'no')
|
263
278
|
# add_property(new_avd_config, 'hw.sdCard', 'yes')
|
279
|
+
add_property(new_avd_config, 'snapshot.present', (!no_snapshot).to_s)
|
264
280
|
File.write(avd_config_file_name, new_avd_config) if new_avd_config != old_avd_config
|
265
281
|
end
|
266
282
|
|
@@ -268,17 +284,23 @@ EOF
|
|
268
284
|
`adb get-state`.gsub(/^WARNING:.*$/, '').chomp == 'device'
|
269
285
|
end
|
270
286
|
|
271
|
-
def
|
287
|
+
def read_property(config, property_name)
|
288
|
+
pattern = /^#{property_name}=(.*)$/
|
289
|
+
config =~ pattern
|
290
|
+
$1
|
291
|
+
end
|
292
|
+
|
293
|
+
def add_property(config, property_name, value)
|
272
294
|
pattern = /^#{property_name}=(.*)$/
|
273
|
-
|
274
|
-
if
|
275
|
-
if
|
276
|
-
|
277
|
-
puts "Changed property: #{
|
295
|
+
new_property = "#{property_name}=#{value}"
|
296
|
+
if (old_property = read_property(config, property_name))
|
297
|
+
if old_property != value
|
298
|
+
config.gsub! pattern, new_property
|
299
|
+
puts "Changed property: #{new_property} (was #{old_property.inspect})"
|
278
300
|
end
|
279
301
|
else
|
280
|
-
|
281
|
-
puts "Added property: #{
|
302
|
+
config << "#{new_property}\n"
|
303
|
+
puts "Added property: #{new_property}"
|
282
304
|
end
|
283
305
|
end
|
284
306
|
end
|