generate_tclloader_omniset()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 22
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nop 5
dl 0
loc 22
rs 10
c 0
b 0
f 0
ccs 4
cts 4
cp 1
crap 1
1
#!/usr/bin/env python3
2 5
"""This module is used for creation of TCL autoloaders."""
3
4 5
import os  # path work
5 5
import shutil  # file copying
6
7 5
from bbarchivist import bbconstants  # versions/constants
8
9 5
__author__ = "Thurask"
10 5
__license__ = "WTFPL v2"
11 5
__copyright__ = "2018-2019 Thurask"
12
13
14 5
def point_point_copy(inpath, outpath, filename):
15
    """
16
    Copy a file from one absolute path to another.
17
18
    :param inpath: Input path.
19
    :type inpath: str
20
21
    :param outpath: Output path.
22
    :type outpath: str
23
24
    :param filename: Filename.
25
    :type filename: str
26
    """
27 5
    if os.sep in filename:
28 5
        filex = os.path.basename(filename)
29
    else:
30 5
        filex = filename
31 5
    shutil.copy(os.path.join(inpath, filename), os.path.join(outpath, filex))
32
33
34 5
def point_point_bulk(inpath, outpath, files):
35
    """
36
    Copy a list of files from one absolute path to another.
37
38
    :param inpath: Input path.
39
    :type inpath: str
40
41
    :param outpath: Output path.
42
    :type outpath: str
43
44
    :param files: List of filenames.
45
    :type files: list(str)
46
    """
47 5
    for file in files:
48 5
        point_point_copy(inpath, outpath, file)
49
50
51 5
def generate_tclloader_script(dirname, batchfile, shfile, wipe=True):
52
    """
53
    Copy script files from site-packages to loader directory.
54
55
    :param dirname: Name for final directory and loader.
56
    :type dirname: str
57
58
    :param batchfile: Path to flashall.bat.
59
    :type batchfile: str
60
61
    :param shfile: Path to flashall.sh.
62
    :type shfile: str
63
64
    :param wipe: If the final loader wipes userdata. Default is True.
65
    :type wipe: bool
66
    """
67 5
    shutil.copy(batchfile, os.path.join(dirname, "flashall.bat"))
68 5
    shutil.copy(shfile, os.path.join(dirname, "flashall.sh"))
69 5
    if not wipe:
70 5
        tclloader_nowipe(os.path.join(dirname, "flashall.bat"))
71 5
        tclloader_nowipe(os.path.join(dirname, "flashall.sh"))
72
73
74 5
def tclloader_nowipe(infile):
75
    """
76
    Modify a script file to strike references to wiping the phone.
77
78
    :param infile: Path to script file to modify.
79
    :type infile: str
80
    """
81 5
    filterout = ("oem securewipe", "flash userdata")
82 5
    with open(infile, "r+", newline="") as afile:
83 5
        content = afile.read()
84 5
        afile.seek(0)
85 5
        for line in content.split("\n"):
86 5
            if not any(part in line for part in filterout):
87 5
                afile.write(line + "\n")
88 5
        afile.truncate()
89
90
91 5
def generate_google_host(hostin, hostout):
92
    """
93
    Generate host directory from Google platform tools, i.e. fastboot.
94
95
    :param hostin: Directory containing files to copy.
96
    :type hostin: str
97
98
    :param hostout: Directory that files are to be copied to.
99
    :type hostout: str
100
    """
101 5
    platforms = ["linux", "windows", "darwin"]
102 5
    inouts = {os.path.join(hostin, plat, "platform-tools"): os.path.join(hostout, "{0}-x86".format(plat), "bin") for plat in platforms}
103 5
    for infile, outfile in inouts.items():
104 5
        shutil.copytree(infile, outfile)
105
106
107 5
def generate_tclloader_host(hostin, hostout):
108
    """
109
    Generate host directory from autoloader template, i.e. fastboot.
110
111
    :param hostin: Directory containing files to copy.
112
    :type hostin: str
113
114
    :param hostout: Directory that files are to be copied to.
115
    :type hostout: str
116
    """
117 5
    os.makedirs(os.path.join(hostout, "darwin-x86", "bin"))
118 5
    os.makedirs(os.path.join(hostout, "linux-x86", "bin"))
119 5
    os.makedirs(os.path.join(hostout, "windows-x86", "bin"))
120 5
    macfile = os.path.join("darwin-x86", "bin", "fastboot")
121 5
    linfile = os.path.join("linux-x86", "bin", "fastboot")
122 5
    winx = ["AdbWinApi.dll", "AdbWinUsbApi.dll", "fastboot.exe"]
123 5
    winfiles = [os.path.join("windows-x86", "bin", x) for x in winx]
124 5
    winfiles.extend([linfile, macfile])
125 5
    point_point_bulk(hostin, hostout, winfiles)
126
127
128 5
def generate_tclloader_sig(sigin, sigout):
129
    """
130
    Generate common signature files.
131
132
    :param sigin: Directory containing files to copy.
133
    :type sigin: str
134
135
    :param sigout: Directory that files are to be copied to.
136
    :type sigout: str
137
    """
138 5
    for entry in ["boot", "recovery"]:
139 5
        shutil.copy(os.path.join(sigin, "{0}.img.production.sig".format(entry)), os.path.join(sigout, "{0}.img.sig".format(entry)))
140
141
142 5
def generate_tclloader_csig(sigin, sigout, carrier):
143
    """
144
    Generate carrier variant signature files.
145
146
    :param sigin: Directory containing files to copy.
147
    :type sigin: str
148
149
    :param sigout: Directory that files are to be copied to.
150
    :type sigout: str
151
152
    :param carrier: Carrier to check: att, sprint, china, vzw
153
    :type carrier: str
154
    """
155 5
    for entry in ["boot", "recovery"]:
156 5
        shutil.copy(os.path.join(sigin, "{1}.img.production-{0}.sig".format(carrier, entry)), os.path.join(sigout, "{1}.img{0}.sig".format(carrier, entry)))
157
158
159 5
def generate_tclloader_carriers(sigin, sigout):
160
    """
161
    Collect carrier variant signature files.
162
163
    :param sigin: Directory containing files to copy.
164
    :type sigin: str
165
166
    :param sigout: Directory that files are to be copied to.
167
    :type sigout: str
168
    """
169 5
    prods = set(x.split("-")[-1].split(".")[0] for x in os.listdir(sigin) if "production-" in x) - {"boot", "recovery"}
170 5
    if prods:
171 5
        generate_tclloader_carriter(sigin, sigout, prods)
172
173
174 5
def generate_tclloader_carriter(sigin, sigout, prods):
175
    """
176
    Iterate carrier variant signature files.
177
178
    :param sigin: Directory containing files to copy.
179
    :type sigin: str
180
181
    :param sigout: Directory that files are to be copied to.
182
    :type sigout: str
183
184
    :param prods: Set of carriers.
185
    :type prods: set(str)
186
    """
187 5
    for carr in prods:
188 5
        generate_tclloader_csig(sigin, sigout, carr)
189
190
191 5
def generate_tclloader_mbn(mbnin, mbnout, platform):
192
    """
193
    Generate mbn files.
194
195
    :param mbnin: Directory containing files to copy.
196
    :type mbnin: str
197
198
    :param mbnout: Directory that files are to be copied to.
199
    :type mbnout: str
200
201
    :param platform: Platform type (i.e. subdirectory of target/product).
202
    :type platform: str
203
    """
204 5
    files = generate_tclloader_platmbn(platform)
205 5
    point_point_bulk(mbnin, mbnout, files)
206
207
208 5
def generate_tclloader_omniset(omnin, omnilist, prefix, suffix, filt):
209
    """
210
    Generic function to generate sets.
211
212
    :param omnin: Directory containing files to copy.
213
    :type omnin: str
214
215
    :param omnilist: List of variants.
216
    :type omnilist: list(str)
217
218
    :param prefix: Prefix, before items in list.
219
    :type prefix: str
220
221
    :param suffix: Suffix, after items in list.
222
    :type suffix: str
223
224
    :param filt: Filter, required to pick file out of directory listing.
225
    :type filt: str
226
    """
227 5
    omfiles = set(os.path.join(omnin, "{1}{0}{2}".format(omni, prefix, suffix)) for omni in omnilist)
228 5
    infiles = set(os.path.join(omnin, filex) for filex in os.listdir(omnin) if filt in filex)
229 5
    return omfiles, infiles
230
231
232 5
def generate_tclloader_oemset(oemin, oems):
233
    """
234
    Generate sets for OEM variants.
235
236
    :param oemin: Directory containing files to copy.
237
    :type oemin: str
238
239
    :param oems: List of OEM variants.
240
    :type oems: list(str)
241
    """
242 5
    ofiles, infiles = generate_tclloader_omniset(oemin, oems, "", ".img", "oem_")
243 5
    return ofiles, infiles
244
245
246 5
def generate_tclloader_oemfilt(oemin, oems):
247
    """
248
    Filter non-existent OEM variants.
249
250
    :param oemin: Directory containing files to copy.
251
    :type oemin: str
252
253
    :param oems: List of OEM variants.
254
    :type oems: list(str)
255
    """
256 5
    ofiles, infiles = generate_tclloader_oemset(oemin, oems)
257 5
    coll = [os.path.basename(oemf).replace(".img", "") for oemf in ofiles - infiles]
258 5
    oems = [oemp for oemp in oems if oemp not in coll]
259 5
    return oems
260
261
262 5
def generate_tclloader_radset(radin, rads):
263
    """
264
    Generate sets for radio variants.
265
266
    :param radin: Directory containing files to copy.
267
    :type radin: str
268
269
    :param rads: List of radio variants.
270
    :type rads: list(str)
271
    """
272 5
    rfiles, infiles = generate_tclloader_omniset(radin, rads, "NON-HLOS-", ".bin", "NON-HLOS-")
273 5
    return rfiles, infiles
274
275
276 5
def generate_tclloader_radfilt(radin, rads):
277
    """
278
    Filter non-existent radio variants.
279
280
    :param radin: Directory containing files to copy.
281
    :type radin: str
282
283
    :param rads: List of radio variants.
284
    :type rads: list(str)
285
    """
286 5
    rfiles, infiles = generate_tclloader_radset(radin, rads)
287 5
    coll = [os.path.basename(radf).replace(".bin", "").replace("NON-HLOS-", "") for radf in rfiles - infiles]
288 5
    rads = [radp for radp in rads if radp not in coll]
289 5
    return rads
290
291
292 5
def generate_tclloader_deps(platform):
293
    """
294
    Generate platform-specific file names.
295
296
    :param platform: Platform type (i.e. subdirectory of target/product).
297
    :type platform: str
298
    """
299 5
    if platform == "bbry_qc8953":  # KEYone
300 5
        oems = ["oem_att", "oem_china", "oem_common", "oem_sprint", "oem_vzw", "oem_indonesia", "oem_russia"]
301 5
        radios = ["china", "dschina", "emea", "global", "india", "japan", "usa"]
302 5
    elif platform == "bbry_qc8953krypton":  # Motion
303 5
        oems = ["oem_att", "oem_common", "oem_sprint", "oem_russia"]
304 5
        radios = ["americas", "cdma", "dscn", "dsglobal", "ssglobal"]
305 5
    elif platform == "bbry_sdm660":  # KEY2
306 5
        oems = ["oem_att", "oem_china", "oem_common", "oem_india", "oem_indonesia", "oem_sprint", "oem_russia", "oem_eea", "oem_b2b"]
307 5
        radios = ["americas", "cn", "dsglobal", "dsjapan", "global", "japan"]
308 5
    elif platform == "bbry_sdm636":  # KEY2LE
309 5
        oems = ["oem_china", "oem_common", "oem_india", "oem_russia", "oem_eea", "oem_b2b"]
310 5
        radios = ["americas", "dsamericas", "global", "dsglobal", "dscn"]
311 5
    return oems, radios
312
313
314 5
def generate_tclloader_looseends(imgout, platform):
315
    """
316
    Handle files that need to be handled.
317
318
    :param imgout: Directory that files are to be copied to.
319
    :type imgout: str
320
321
    :param platform: Platform type (i.e. subdirectory of target/product).
322
    :type platform: str
323
    """
324 5
    if platform == "bbry_qc8953":  # KEYone
325 5
        pass  # no special exceptions
326 5
    elif platform == "bbry_qc8953krypton":  # Motion
327 5
        looseends_krypton(imgout)
328 5
    elif platform in ("bbry_sdm660", "bbry_sdm636"):  # KEY2/KEY2LE
329 5
        pass  # no special exceptions
330
331
332 5
def looseends_krypton(imgout):
333
    """
334
    Handle files that need to be handled, for the Motion platform.
335
336
    :param imgout: Directory that files are to be copied to.
337
    :type imgout: str
338
    """
339 5
    oldglobal = os.path.join(imgout, "NON-HLOS-ssglobal.bin")
340 5
    newglobal = os.path.join(imgout, "NON-HLOS-global.bin")
341 5
    os.rename(oldglobal, newglobal)  # SS intl model has different name than modem
342 5
    oldamericas = os.path.join(imgout, "NON-HLOS-americas.bin")
343 5
    newamericas = os.path.join(imgout, "NON-HLOS-dsamericas.bin")
344 5
    shutil.copy(oldamericas, newamericas)  # DS/SS americas model use same modem
345
346
347 5
def generate_tclloader_platimg(platform):
348
    """
349
    Generate platform-specific .img files.
350
351
    :param platform: Platform type (i.e. subdirectory of target/product).
352
    :type platform: str
353
    """
354 5
    imgs = ["recovery", "system", "userdata", "cache", "boot"]
355 5
    if platform in ("bbry_sdm660", "bbry_sdm636"):
356 5
        imgs.append("vendor")
357 5
    return imgs
358
359
360 5
def generate_tclloader_platmbn(platform):
361
    """
362
    Generate platform-specific MBN files.
363
364
    :param platform: Platform type (i.e. subdirectory of target/product).
365
    :type platform: str
366
    """
367 5
    if platform in ("bbry_sdm660", "bbry_sdm636"):
368 5
        mbnx = ["devcfg.mbn", "pmic.elf", "xbl.elf", "rpm.mbn", "tz.mbn"]
369 5
        mbny = ["hyp.signed.mbn", "cmnlib.signed.mbn", "cmnlib64.signed.mbn", "keymaster64.signed.mbn", "mdtpsecapp.signed.mbn"]
370 5
        mbnz = [os.path.join("MBNs", mbn) for mbn in mbny]
371 5
        mbns = mbnx + mbnz
372 5
    elif platform in ("bbry_qc8953", "bbry_qc8953krypton"):
373 5
        mbns = ["devcfg.mbn", "devcfg_cn.mbn", "rpm.mbn", "tz.mbn"]
374
    else:
375 5
        mbns = [None]
376 5
    return mbns
377
378
379 5
def generate_tclloader_platother(platform):
380
    """
381
    Generate platform-specific other files.
382
383
    :param platform: Platform type (i.e. subdirectory of target/product).
384
    :type platform: str
385
    """
386 5
    if platform in ("bbry_sdm660", "bbry_sdm636"):
387 5
        others = ["dspso.bin", "BTFM.bin", "abl.elf"]
388 5
    elif platform in ("bbry_qc8953", "bbry_qc8953krypton"):
389 5
        others = ["adspso.bin", "emmc_appsboot.mbn", "sbl1_signed.mbn"]
390
    else:
391 5
        others = [None]
392 5
    return others
393
394
395 5
def generate_tclloader_img(imgin, imgout, platform):
396
    """
397
    Generate partition images and radios.
398
399
    :param imgin: Directory containing files to copy.
400
    :type imgin: str
401
402
    :param imgout: Directory that files are to be copied to.
403
    :type imgout: str
404
405
    :param platform: Platform type (i.e. subdirectory of target/product).
406
    :type platform: str
407
    """
408 5
    imgs = generate_tclloader_platimg(platform)
409 5
    point_point_bulk(imgin, imgout, ["{0}.img".format(img) for img in imgs])
410 5
    oems, radios = generate_tclloader_deps(platform)
411 5
    oems = generate_tclloader_oemfilt(imgin, oems)
412 5
    point_point_bulk(imgin, imgout, ["{0}.img".format(oem) for oem in oems])
413 5
    radios = generate_tclloader_radfilt(imgin, radios)
414 5
    point_point_bulk(imgin, imgout, ["NON-HLOS-{0}.bin".format(rad) for rad in radios])
415 5
    others = generate_tclloader_platother(platform)
416 5
    point_point_bulk(imgin, imgout, others)
417 5
    generate_tclloader_looseends(imgout, platform)
418
419
420 5
def generate_tclloader_scripttype(platform):
421
    """
422
    Get the right scripts for the right platform.
423
424
    :param platform: Platform type (i.e. subdirectory of target/product).
425
    :type platform: str
426
    """
427 5
    if platform in ("bbry_sdm660", "bbry_sdm636"):
428 5
        scripts = (bbconstants.FLASHBATBBF.location, bbconstants.FLASHSHBBF.location)
429 5
    elif platform in ("bbry_qc8953", "bbry_qc8953krypton"):
430 5
        scripts = (bbconstants.FLASHBAT.location, bbconstants.FLASHSH.location)
431
    else:
432 5
        scripts = (None, None)
433 5
    return scripts
434
435
436 5
def generate_tclloader(localdir, dirname, platform, localtools=False, wipe=True):
437
    """
438
    Generate Android loader from extracted template files.
439
440
    :param localdir: Directory containing extracted template files.
441
    :type localdir: str
442
443
    :param dirname: Name for final directory and loader.
444
    :type dirname: str
445
446
    :param platform: Platform type (i.e. subdirectory of target/product).
447
    :type platform: str
448
449
    :param localtools: If host files will be copied from a template rather than a download. Default is False.
450
    :type localtools: bool
451
452
    :param wipe: If the final loader wipes userdata. Default is True.
453
    :type wipe: bool
454
    """
455 5
    if not os.path.exists(dirname):
456 5
        os.makedirs(dirname)
457 5
    hostdir = os.path.join(dirname, "host")
458 5
    os.makedirs(hostdir)
459 5
    imgdir = os.path.join(dirname, "img")
460 5
    os.makedirs(imgdir)
461 5
    platscripts = generate_tclloader_scripttype(platform)
462 5
    generate_tclloader_script(dirname, platscripts[0], platscripts[1], wipe)
463 5
    if localtools:
464 5
        hdir = os.path.join(localdir, "host")
465 5
        generate_tclloader_host(hdir, hostdir)
466
    else:
467 5
        platdir = "plattools"
468 5
        generate_google_host(platdir, hostdir)
469 5
    pdir = os.path.join(localdir, "target", "product", platform)
470 5
    generate_tclloader_img(pdir, imgdir, platform)
471 5
    sdir = os.path.join(pdir, "sig")
472 5
    generate_tclloader_sig(sdir, imgdir)
473 5
    generate_tclloader_carriers(sdir, imgdir)
474 5
    qdir = os.path.join(pdir, "qcbc")
475
    generate_tclloader_mbn(qdir, imgdir, platform)
476