channel_action.py 3.7 KB
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path
from xml.etree import ElementTree as ET
from xml.etree.ElementTree import SubElement
from xml.etree.ElementTree import Element
from xml.etree.ElementTree import ElementTree
import os
import os.path
import zipfile
import re
import subprocess
import platform
from xml.dom import minidom
import codecs
import sys

androidNS = 'http://schemas.android.com/apk/res/android'

def execute(channel, decompileDir, packageName):
    modify_manifest(channel, decompileDir, packageName)

    manifest_path = decompileDir + '/AndroidManifest.xml'
    find_launch_activity(manifest_path)

    return 0


def modify_manifest(channel, decompileDir, packageName):
    sdkDir = decompileDir + '/../sdk/' + channel['sdk']
    if not os.path.exists(sdkDir):
        file_utils.printF("The sdk temp folder is not exists. path:"+sdkDir)
        return 1

    manifest = decompileDir + '/AndroidManifest.xml'
    ET.register_namespace('android', androidNS)
    
    key = '{' + androidNS + '}name'

    tree = ET.parse(manifest)
    root = tree.getroot()

    applicationNode = root.find('application')
    if applicationNode is None:
        return 1

    providerNodeLst = applicationNode.findall('provider')
    if providerNodeLst is None:
        return 1

    for providerNode in providerNodeLst:
        name = providerNode.get(key)
        authorKey = '{' + androidNS + '}authorities'
        if name == 'android.support.v4.content.FileProvider':
            providerNode.set(authorKey, packageName + '.fileProvider')

    tree.write(manifest, 'UTF-8')

    manifest_file = open(manifest, 'r+', encoding='Utf-8')
    manifestContent = str(manifest_file.read())
    manifest_file.close()

    manifestContent = manifestContent.replace('android:launchMode="singleTask"', 'android:launchMode="standard"')

    manifest_new_file = open(manifest, 'w', encoding='Utf-8')
    manifest_new_file.write(manifestContent)
    manifest_new_file.close()

    return 0


def find_launch_activity(manifest_path):
    ET.register_namespace("android", androidNS)
    tree = ET.parse(manifest_path)
    root = tree.getroot()

    for activity in root.findall('.//activity'):
        intent_filter = activity.find('.//intent-filter')
        if intent_filter is not None:
            action = intent_filter.find('.//action')
            if action is not None and action.get('{' + androidNS + '}name') == 'android.intent.action.MAIN':
                origin_activity_name = activity.get('{' + androidNS + '}name')
                print(origin_activity_name)
                activity.remove(intent_filter)
                tree.write(manifest_path)
                manifest_add(manifest_path, tree, root, origin_activity_name)
                break


def manifest_add(manifest_path, tree, root, origin_activity_name):
    namespace2 = {'android': 'http://schemas.android.com/apk/res/android'}
    target_activity = root.find(".//activity[@android:name='com.stss.sdk.SplashActivity']",
                                namespace2)

    if target_activity is None:
        return "SplashActivity not found"

    intent_filter = target_activity.find('intent-filter')
    if intent_filter is None:
        intent_filter = ET.SubElement(target_activity, 'intent-filter')

    action_element = ET.SubElement(intent_filter, 'action')
    action_element.set('{' + androidNS + '}name', 'android.intent.action.MAIN')

    category_element = ET.SubElement(intent_filter, 'category')
    category_element.set('{' + androidNS + '}name', 'android.intent.category.LAUNCHER')

    meta_data = ET.SubElement(target_activity, 'meta-data')
    meta_data.set('android:name', "GAME_ACTIVITY")
    meta_data.set('android:value', origin_activity_name)

    tree.write(manifest_path)