run_loop 1.5.5 → 1.5.6.pre1
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/lib/run_loop/cli/simctl.rb +37 -82
- data/lib/run_loop/core.rb +20 -17
- data/lib/run_loop/core_simulator.rb +648 -0
- data/lib/run_loop/device.rb +8 -8
- data/lib/run_loop/directory.rb +104 -17
- data/lib/run_loop/dot_dir.rb +83 -0
- data/lib/run_loop/environment.rb +27 -8
- data/lib/run_loop/instruments.rb +89 -1
- data/lib/run_loop/logging.rb +11 -0
- data/lib/run_loop/process_terminator.rb +5 -17
- data/lib/run_loop/sim_control.rb +114 -77
- data/lib/run_loop/version.rb +15 -3
- data/lib/run_loop.rb +9 -10
- metadata +6 -7
- data/lib/run_loop/life_cycle/core_simulator.rb +0 -515
- data/lib/run_loop/life_cycle/simulator.rb +0 -73
- data/lib/run_loop/simctl/bridge.rb +0 -499
@@ -1,73 +0,0 @@
|
|
1
|
-
module RunLoop
|
2
|
-
|
3
|
-
# @!visibility private
|
4
|
-
module LifeCycle
|
5
|
-
|
6
|
-
# @!visibility private
|
7
|
-
#
|
8
|
-
# Defines a Life Cycle interface for Simulators.
|
9
|
-
class Simulator
|
10
|
-
|
11
|
-
# @!visibility private
|
12
|
-
# Pattern.
|
13
|
-
# [ '< process name >', < send term first > ]
|
14
|
-
MANAGED_PROCESSES =
|
15
|
-
[
|
16
|
-
# This process is a daemon, and requires 'KILL' to terminate.
|
17
|
-
# Killing the process is fast, but it takes a long time to
|
18
|
-
# restart.
|
19
|
-
# ['com.apple.CoreSimulator.CoreSimulatorService', false],
|
20
|
-
|
21
|
-
# Probably do not need to quit this, but it is tempting to do so.
|
22
|
-
#['com.apple.CoreSimulator.SimVerificationService', false],
|
23
|
-
|
24
|
-
# Started by Xamarin Studio, this is the parent process of the
|
25
|
-
# processes launched by Xamarin's interaction with
|
26
|
-
# CoreSimulatorBridge.
|
27
|
-
['csproxy', true],
|
28
|
-
|
29
|
-
# Yes.
|
30
|
-
['SimulatorBridge', true],
|
31
|
-
['configd_sim', true],
|
32
|
-
['launchd_sim', true],
|
33
|
-
|
34
|
-
# Does not always appear.
|
35
|
-
['CoreSimulatorBridge', true],
|
36
|
-
|
37
|
-
# assetsd instances clobber each other and are not properly
|
38
|
-
# killed when quiting the simulator.
|
39
|
-
['assetsd', true],
|
40
|
-
|
41
|
-
# iproxy is started by UITest. It is not necessary to send
|
42
|
-
# TERM first.
|
43
|
-
['iproxy', false],
|
44
|
-
|
45
|
-
# Xcode 7
|
46
|
-
['ids_simd', true]
|
47
|
-
]
|
48
|
-
|
49
|
-
# @!visibility private
|
50
|
-
def terminate_core_simulator_processes
|
51
|
-
MANAGED_PROCESSES.each do |pair|
|
52
|
-
name = pair[0]
|
53
|
-
send_term = pair[1]
|
54
|
-
pids = RunLoop::ProcessWaiter.new(name).pids
|
55
|
-
pids.each do |pid|
|
56
|
-
|
57
|
-
if send_term
|
58
|
-
term = RunLoop::ProcessTerminator.new(pid, 'TERM', name)
|
59
|
-
killed = term.kill_process
|
60
|
-
else
|
61
|
-
killed = false
|
62
|
-
end
|
63
|
-
|
64
|
-
unless killed
|
65
|
-
term = RunLoop::ProcessTerminator.new(pid, 'KILL', name)
|
66
|
-
term.kill_process
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,499 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
require 'open3'
|
3
|
-
#require 'retriable'
|
4
|
-
|
5
|
-
module RunLoop::Simctl
|
6
|
-
|
7
|
-
class SimctlError < StandardError
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
# @!visibility private
|
12
|
-
# This is not a public API. You have been warned.
|
13
|
-
#
|
14
|
-
# TODO Some code is duplicated from sim_control.rb
|
15
|
-
# TODO Reinstall if checksum does not match.
|
16
|
-
# TODO Analyze terminate_core_simulator_processes.
|
17
|
-
# TODO Figure out when CoreSimulator appears and does not appear.
|
18
|
-
class Bridge < RunLoop::LifeCycle::CoreSimulator
|
19
|
-
|
20
|
-
attr_reader :device
|
21
|
-
attr_reader :app
|
22
|
-
attr_reader :sim_control
|
23
|
-
attr_reader :pbuddy
|
24
|
-
|
25
|
-
def initialize(device, app_bundle_path)
|
26
|
-
|
27
|
-
@pbuddy = RunLoop::PlistBuddy.new
|
28
|
-
|
29
|
-
@sim_control = RunLoop::SimControl.new
|
30
|
-
@path_to_ios_sim_app_bundle = @sim_control.send(:sim_app_path)
|
31
|
-
|
32
|
-
@app = RunLoop::App.new(app_bundle_path)
|
33
|
-
|
34
|
-
unless @app.valid?
|
35
|
-
raise "Could not recreate a valid app from '#{app_bundle_path}'"
|
36
|
-
end
|
37
|
-
|
38
|
-
@device = device
|
39
|
-
|
40
|
-
# It may seem weird to do this in the initialize, but you cannot make
|
41
|
-
# simctl calls successfully unless the simulator is:
|
42
|
-
# 1. closed
|
43
|
-
# 2. the device you are trying to operate on is Shutdown
|
44
|
-
# 3. the CoreSimulator processes are terminated
|
45
|
-
RunLoop::SimControl.terminate_all_sims
|
46
|
-
shutdown
|
47
|
-
terminate_core_simulator_processes
|
48
|
-
end
|
49
|
-
|
50
|
-
# The sha1 of the installed app.
|
51
|
-
def installed_app_sha1
|
52
|
-
installed_bundle = fetch_app_dir
|
53
|
-
if installed_bundle
|
54
|
-
RunLoop::Directory.directory_digest(installed_bundle)
|
55
|
-
else
|
56
|
-
nil
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# Is the app that is install the same as the one we have in hand?
|
61
|
-
def same_sha1_as_installed?
|
62
|
-
app.sha1 == installed_app_sha1
|
63
|
-
end
|
64
|
-
|
65
|
-
# @!visibility private
|
66
|
-
def is_sdk_8?
|
67
|
-
@is_sdk_8 ||= device.version >= RunLoop::Version.new('8.0')
|
68
|
-
end
|
69
|
-
|
70
|
-
def device_data_dir
|
71
|
-
@device_data_dir ||= File.join(CORE_SIMULATOR_DEVICE_DIR, device.udid, 'data')
|
72
|
-
end
|
73
|
-
|
74
|
-
def device_applications_dir
|
75
|
-
@simulator_app_dir ||= lambda {
|
76
|
-
if is_sdk_8?
|
77
|
-
File.join(device_data_dir, 'Containers', 'Bundle', 'Application')
|
78
|
-
else
|
79
|
-
File.join(device_data_dir, 'Applications')
|
80
|
-
end
|
81
|
-
}.call
|
82
|
-
end
|
83
|
-
|
84
|
-
def app_data_dir
|
85
|
-
app_install_dir = fetch_app_dir
|
86
|
-
return nil if app_install_dir.nil?
|
87
|
-
if is_sdk_8?
|
88
|
-
containers_data_dir = File.join(device_data_dir, 'Containers', 'Data', 'Application')
|
89
|
-
apps = Dir.glob("#{containers_data_dir}/**/#{METADATA_PLIST}")
|
90
|
-
match = apps.detect do |metadata_plist|
|
91
|
-
pbuddy.plist_read('MCMMetadataIdentifier', metadata_plist) == app.bundle_identifier
|
92
|
-
end
|
93
|
-
if match
|
94
|
-
File.dirname(match)
|
95
|
-
else
|
96
|
-
nil
|
97
|
-
end
|
98
|
-
else
|
99
|
-
app_install_dir
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def app_library_dir
|
104
|
-
base_dir = app_data_dir
|
105
|
-
if base_dir.nil?
|
106
|
-
nil
|
107
|
-
else
|
108
|
-
File.join(base_dir, 'Library')
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def app_library_preferences_dir
|
113
|
-
base_dir = app_library_dir
|
114
|
-
if base_dir.nil?
|
115
|
-
nil
|
116
|
-
else
|
117
|
-
File.join(base_dir, 'Preferences')
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def app_documents_dir
|
122
|
-
base_dir = app_data_dir
|
123
|
-
if base_dir.nil?
|
124
|
-
nil
|
125
|
-
else
|
126
|
-
File.join(base_dir, 'Documents')
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def app_tmp_dir
|
131
|
-
base_dir = app_data_dir
|
132
|
-
if base_dir.nil?
|
133
|
-
nil
|
134
|
-
else
|
135
|
-
File.join(base_dir, 'tmp')
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def reset_app_sandbox
|
140
|
-
return true if !app_is_installed?
|
141
|
-
|
142
|
-
shutdown
|
143
|
-
|
144
|
-
reset_app_sandbox_internal
|
145
|
-
end
|
146
|
-
|
147
|
-
def update_device_state(options={})
|
148
|
-
merged_options = UPDATE_DEVICE_STATE_OPTS.merge(options)
|
149
|
-
|
150
|
-
interval = merged_options[:interval]
|
151
|
-
tries = merged_options[:tries]
|
152
|
-
|
153
|
-
debug_logging = RunLoop::Environment.debug?
|
154
|
-
|
155
|
-
on_retry = Proc.new do |_, try, elapsed_time, next_interval|
|
156
|
-
if debug_logging
|
157
|
-
# Retriable 2.0
|
158
|
-
if elapsed_time && next_interval
|
159
|
-
puts "Updating device state attempt #{try} failed in '#{elapsed_time}'; will retry in '#{next_interval}'"
|
160
|
-
else
|
161
|
-
puts "Updating device state attempt #{try} failed; will retry in #{interval}"
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
retry_opts = RunLoop::RetryOpts.tries_and_interval(tries, interval,
|
167
|
-
{:on_retry => on_retry,
|
168
|
-
:on => [SimctlError]
|
169
|
-
})
|
170
|
-
matching_device = nil
|
171
|
-
|
172
|
-
Retriable.retriable(retry_opts) do
|
173
|
-
matching_device = fetch_matching_device
|
174
|
-
|
175
|
-
unless matching_device
|
176
|
-
raise "simctl could not find device with '#{device.udid}'"
|
177
|
-
end
|
178
|
-
|
179
|
-
if matching_device.state == nil || matching_device.state == ''
|
180
|
-
raise SimctlError, "Could not find the state of the device with #{device.udid}"
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
# Device#state is immutable
|
185
|
-
@device = matching_device
|
186
|
-
@device.state
|
187
|
-
end
|
188
|
-
|
189
|
-
def wait_for_device_state(target_state)
|
190
|
-
return true if update_device_state == target_state
|
191
|
-
|
192
|
-
now = Time.now
|
193
|
-
timeout = WAIT_FOR_DEVICE_STATE_OPTS[:timeout]
|
194
|
-
poll_until = now + WAIT_FOR_DEVICE_STATE_OPTS[:timeout]
|
195
|
-
delay = WAIT_FOR_DEVICE_STATE_OPTS[:interval]
|
196
|
-
in_state = false
|
197
|
-
while Time.now < poll_until
|
198
|
-
in_state = update_device_state == target_state
|
199
|
-
break if in_state
|
200
|
-
sleep delay
|
201
|
-
end
|
202
|
-
|
203
|
-
if RunLoop::Environment.debug?
|
204
|
-
puts "Waited for #{timeout} seconds for device to have state: '#{target_state}'."
|
205
|
-
end
|
206
|
-
|
207
|
-
unless in_state
|
208
|
-
raise "Expected '#{target_state} but found '#{device.state}' after waiting."
|
209
|
-
end
|
210
|
-
in_state
|
211
|
-
end
|
212
|
-
|
213
|
-
def app_is_installed?
|
214
|
-
!fetch_app_dir.nil?
|
215
|
-
end
|
216
|
-
|
217
|
-
# @!visibility private
|
218
|
-
def fetch_app_dir
|
219
|
-
sim_app_dir = device_applications_dir
|
220
|
-
return nil if !File.exist?(sim_app_dir)
|
221
|
-
Dir.glob("#{sim_app_dir}/**/*.app").detect(nil) do |path|
|
222
|
-
RunLoop::App.new(path).bundle_identifier == app.bundle_identifier
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
def wait_for_app_install
|
227
|
-
return true if app_is_installed?
|
228
|
-
|
229
|
-
now = Time.now
|
230
|
-
timeout = WAIT_FOR_APP_INSTALL_OPTS[:timeout]
|
231
|
-
poll_until = now + timeout
|
232
|
-
delay = WAIT_FOR_APP_INSTALL_OPTS[:interval]
|
233
|
-
is_installed = false
|
234
|
-
while Time.now < poll_until
|
235
|
-
is_installed = app_is_installed?
|
236
|
-
break if is_installed
|
237
|
-
sleep delay
|
238
|
-
end
|
239
|
-
|
240
|
-
if RunLoop::Environment.debug?
|
241
|
-
puts "Waited for #{timeout} seconds for '#{app.bundle_identifier}' to install."
|
242
|
-
end
|
243
|
-
|
244
|
-
unless is_installed
|
245
|
-
raise "Expected app to be installed on #{device.instruments_identifier}"
|
246
|
-
end
|
247
|
-
|
248
|
-
true
|
249
|
-
end
|
250
|
-
|
251
|
-
def wait_for_app_uninstall
|
252
|
-
return true unless app_is_installed?
|
253
|
-
|
254
|
-
now = Time.now
|
255
|
-
timeout = WAIT_FOR_APP_INSTALL_OPTS[:timeout]
|
256
|
-
poll_until = now + timeout
|
257
|
-
delay = WAIT_FOR_APP_INSTALL_OPTS[:interval]
|
258
|
-
not_installed = false
|
259
|
-
while Time.now < poll_until
|
260
|
-
not_installed = !app_is_installed?
|
261
|
-
break if not_installed
|
262
|
-
sleep delay
|
263
|
-
end
|
264
|
-
|
265
|
-
if RunLoop::Environment.debug?
|
266
|
-
puts "Waited for #{timeout} seconds for '#{app.bundle_identifier}' to uninstall."
|
267
|
-
end
|
268
|
-
|
269
|
-
unless not_installed
|
270
|
-
raise "Expected app to be installed on #{device.instruments_identifier}"
|
271
|
-
end
|
272
|
-
|
273
|
-
true
|
274
|
-
end
|
275
|
-
|
276
|
-
def shutdown
|
277
|
-
return true if update_device_state == 'Shutdown'
|
278
|
-
|
279
|
-
if device.state != 'Booted'
|
280
|
-
raise "Cannot handle state '#{device.state}' for #{device.instruments_identifier}"
|
281
|
-
end
|
282
|
-
|
283
|
-
args = "simctl shutdown #{device.udid}".split(' ')
|
284
|
-
Open3.popen3('xcrun', *args) do |_, _, stderr, status|
|
285
|
-
err = stderr.read.strip
|
286
|
-
exit_status = status.value.exitstatus
|
287
|
-
if exit_status != 0
|
288
|
-
raise "Could not shutdown #{device.instruments_identifier}: #{exit_status} => '#{err}'"
|
289
|
-
end
|
290
|
-
end
|
291
|
-
wait_for_device_state('Shutdown')
|
292
|
-
end
|
293
|
-
|
294
|
-
def boot
|
295
|
-
return true if update_device_state == 'Booted'
|
296
|
-
|
297
|
-
if device.state != 'Shutdown'
|
298
|
-
raise "Cannot handle state '#{device.state}' for #{device.instruments_identifier}"
|
299
|
-
end
|
300
|
-
|
301
|
-
args = "simctl boot #{device.udid}".split(' ')
|
302
|
-
Open3.popen3('xcrun', *args) do |_, _, stderr, status|
|
303
|
-
err = stderr.read.strip
|
304
|
-
exit_status = status.value.exitstatus
|
305
|
-
if exit_status != 0
|
306
|
-
raise "Could not boot #{device.instruments_identifier}: #{exit_status} => '#{err}'"
|
307
|
-
end
|
308
|
-
end
|
309
|
-
wait_for_device_state('Booted')
|
310
|
-
end
|
311
|
-
|
312
|
-
def install
|
313
|
-
return true if app_is_installed?
|
314
|
-
|
315
|
-
boot
|
316
|
-
|
317
|
-
args = "simctl install #{device.udid} #{app.path}".split(' ')
|
318
|
-
Open3.popen3('xcrun', *args) do |_, _, stderr, process_status|
|
319
|
-
err = stderr.read.strip
|
320
|
-
exit_status = process_status.value.exitstatus
|
321
|
-
if exit_status != 0
|
322
|
-
raise "Could not install '#{app.bundle_identifier}': #{exit_status} => '#{err}'."
|
323
|
-
end
|
324
|
-
end
|
325
|
-
|
326
|
-
wait_for_app_install
|
327
|
-
shutdown
|
328
|
-
end
|
329
|
-
|
330
|
-
def uninstall
|
331
|
-
return true unless app_is_installed?
|
332
|
-
|
333
|
-
boot
|
334
|
-
|
335
|
-
args = "simctl uninstall #{device.udid} #{app.bundle_identifier}".split(' ')
|
336
|
-
Open3.popen3('xcrun', *args) do |_, _, stderr, process_status|
|
337
|
-
err = stderr.read.strip
|
338
|
-
exit_status = process_status.value.exitstatus
|
339
|
-
if exit_status != 0
|
340
|
-
raise "Could not uninstall '#{app.bundle_identifier}': #{exit_status} => '#{err}'."
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
wait_for_app_uninstall
|
345
|
-
shutdown
|
346
|
-
end
|
347
|
-
|
348
|
-
def launch_simulator
|
349
|
-
args = ['open', '-g', '-a', @path_to_ios_sim_app_bundle, '--args', '-CurrentDeviceUDID', device.udid]
|
350
|
-
pid = spawn('xcrun', *args)
|
351
|
-
Process.detach(pid)
|
352
|
-
|
353
|
-
# @todo Does not always appear?
|
354
|
-
# RunLoop::ProcessWaiter.new('CoreSimulatorBridge', WAIT_FOR_APP_LAUNCH_OPTS).wait_for_any
|
355
|
-
sim_name = @sim_control.send(:sim_name)
|
356
|
-
RunLoop::ProcessWaiter.new(sim_name, WAIT_FOR_APP_LAUNCH_OPTS).wait_for_any
|
357
|
-
RunLoop::ProcessWaiter.new('SimulatorBridge', WAIT_FOR_APP_LAUNCH_OPTS).wait_for_any
|
358
|
-
wait_for_device_state 'Booted'
|
359
|
-
sleep(SIM_POST_LAUNCH_WAIT)
|
360
|
-
end
|
361
|
-
|
362
|
-
def launch
|
363
|
-
|
364
|
-
install
|
365
|
-
launch_simulator
|
366
|
-
|
367
|
-
args = "simctl launch #{device.udid} #{app.bundle_identifier}".split(' ')
|
368
|
-
Open3.popen3('xcrun', *args) do |_, _, stderr, process_status|
|
369
|
-
err = stderr.read.strip
|
370
|
-
exit_status = process_status.value.exitstatus
|
371
|
-
unless exit_status == 0
|
372
|
-
raise "Could not simctl launch '#{app.bundle_identifier}' on '#{device.instruments_identifier}': #{exit_status} => '#{err}'"
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
|
-
RunLoop::ProcessWaiter.new(app.executable_name, WAIT_FOR_APP_LAUNCH_OPTS).wait_for_any
|
377
|
-
true
|
378
|
-
end
|
379
|
-
|
380
|
-
private
|
381
|
-
|
382
|
-
WAIT_FOR_DEVICE_STATE_OPTS =
|
383
|
-
{
|
384
|
-
interval: 0.1,
|
385
|
-
timeout: 5
|
386
|
-
}
|
387
|
-
|
388
|
-
WAIT_FOR_APP_INSTALL_OPTS =
|
389
|
-
{
|
390
|
-
interval: 0.1,
|
391
|
-
timeout: 20
|
392
|
-
}
|
393
|
-
|
394
|
-
WAIT_FOR_APP_LAUNCH_OPTS =
|
395
|
-
{
|
396
|
-
timeout: 10,
|
397
|
-
raise_on_timeout: true
|
398
|
-
}
|
399
|
-
|
400
|
-
UPDATE_DEVICE_STATE_OPTS =
|
401
|
-
{
|
402
|
-
:tries => 100,
|
403
|
-
:interval => 0.1
|
404
|
-
}
|
405
|
-
|
406
|
-
SIM_POST_LAUNCH_WAIT = RunLoop::Environment.sim_post_launch_wait || 1.0
|
407
|
-
|
408
|
-
METADATA_PLIST = '.com.apple.mobile_container_manager.metadata.plist'
|
409
|
-
CORE_SIMULATOR_DEVICE_DIR = File.expand_path('~/Library/Developer/CoreSimulator/Devices')
|
410
|
-
|
411
|
-
# @!visibility private
|
412
|
-
def fetch_matching_device
|
413
|
-
sim_control.simulators.detect do |sim|
|
414
|
-
sim.udid == device.udid
|
415
|
-
end
|
416
|
-
end
|
417
|
-
|
418
|
-
# @!visibility private
|
419
|
-
def reset_app_sandbox_internal_shared
|
420
|
-
[app_documents_dir, app_tmp_dir].each do |dir|
|
421
|
-
FileUtils.rm_rf dir
|
422
|
-
FileUtils.mkdir dir
|
423
|
-
end
|
424
|
-
end
|
425
|
-
|
426
|
-
# @!visibility private
|
427
|
-
def reset_app_sandbox_internal_sdk_gte_8
|
428
|
-
lib_dir = app_library_dir
|
429
|
-
RunLoop::Directory.recursive_glob_for_entries(lib_dir).each do |entry|
|
430
|
-
if entry.include?('Preferences')
|
431
|
-
# nop
|
432
|
-
else
|
433
|
-
if File.exist?(entry)
|
434
|
-
FileUtils.rm_rf(entry)
|
435
|
-
end
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
|
-
prefs_dir = app_library_preferences_dir
|
440
|
-
protected = ['com.apple.UIAutomation.plist',
|
441
|
-
'com.apple.UIAutomationPlugIn.plist']
|
442
|
-
RunLoop::Directory.recursive_glob_for_entries(prefs_dir).each do |entry|
|
443
|
-
unless protected.include?(File.basename(entry))
|
444
|
-
if File.exist?(entry)
|
445
|
-
FileUtils.rm_rf entry
|
446
|
-
end
|
447
|
-
end
|
448
|
-
end
|
449
|
-
end
|
450
|
-
|
451
|
-
# @!visibility private
|
452
|
-
def reset_app_sandbox_internal_sdk_lt_8
|
453
|
-
prefs_dir = app_library_preferences_dir
|
454
|
-
RunLoop::Directory.recursive_glob_for_entries(prefs_dir).each do |entry|
|
455
|
-
if entry.end_with?('.GlobalPreferences.plist') ||
|
456
|
-
entry.end_with?('com.apple.PeoplePicker.plist')
|
457
|
-
# nop
|
458
|
-
else
|
459
|
-
if File.exist?(entry)
|
460
|
-
FileUtils.rm_rf entry
|
461
|
-
end
|
462
|
-
end
|
463
|
-
end
|
464
|
-
|
465
|
-
# app preferences lives in device Library/Preferences
|
466
|
-
device_prefs_dir = File.join(app_data_dir, 'Library', 'Preferences')
|
467
|
-
app_prefs_plist = File.join(device_prefs_dir, "#{app.bundle_identifier}.plist")
|
468
|
-
if File.exist?(app_prefs_plist)
|
469
|
-
FileUtils.rm_rf(app_prefs_plist)
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
|
-
# @!visibility private
|
474
|
-
def reset_app_sandbox_internal
|
475
|
-
reset_app_sandbox_internal_shared
|
476
|
-
|
477
|
-
if is_sdk_8?
|
478
|
-
reset_app_sandbox_internal_sdk_gte_8
|
479
|
-
else
|
480
|
-
reset_app_sandbox_internal_sdk_lt_8
|
481
|
-
end
|
482
|
-
end
|
483
|
-
|
484
|
-
# @!visibility private
|
485
|
-
def app_uia_crash_logs
|
486
|
-
base_dir = app_data_dir
|
487
|
-
if base_dir.nil?
|
488
|
-
nil
|
489
|
-
else
|
490
|
-
dir = File.join(base_dir, 'Library', 'CrashReporter', 'UIALogs')
|
491
|
-
if Dir.exist?(dir)
|
492
|
-
Dir.glob("#{dir}/*.plist")
|
493
|
-
else
|
494
|
-
nil
|
495
|
-
end
|
496
|
-
end
|
497
|
-
end
|
498
|
-
end
|
499
|
-
end
|