예제 #1
0
"""
获取 app 详细列表信息
"""
import json

from ios_device.servers.DTXSever import DTXServerRPC
from ios_device.servers.Instrument import InstrumentServer


def applictionListing(rpc: DTXServerRPC):
    ret = rpc.call(
        "com.apple.instruments.server.services.device.applictionListing",
        "installedApplicationsMatching:registerUpdateToken:", {}, "")
    print(json.dumps(ret.parsed, indent=4))
    rpc.stop()


if __name__ == '__main__':
    rpc = InstrumentServer().init()
    applictionListing(rpc)
    rpc.deinit()
예제 #2
0
    def run(self) -> None:
        def _callback(res):
            logging.info(f" {res.parsed} : {get_auxiliary_text(res.raw)}")

        self.lockdown = LockdownClient(udid=self.udid)
        installation = InstallationProxy(lockdown=self.lockdown)
        app_info = installation.find_bundle_id(self.bundle_id)
        if not app_info:
            raise Exception("No app matches", self.bundle_id)
        logging.info("BundleID: %s", self.bundle_id)
        logging.info("DeviceIdentifier: %s", self.lockdown.device_info.get('UniqueDeviceID'))
        sign_identity = app_info.get("SignerIdentity", "")
        logging.info("SignIdentity: %r", sign_identity)
        XCODE_VERSION = 29
        session_identifier = NSUUID('96508379-4d3b-4010-87d1-6483300a7b76')
        ManagerdLockdown1 = TestManagerdLockdown(self.lockdown).init()

        ManagerdLockdown1._make_channel("dtxproxy:XCTestManager_IDEInterface:XCTestManager_DaemonConnectionInterface")
        if self.lockdown.ios_version > LooseVersion('11.0'):
            result = ManagerdLockdown1.call(
                "dtxproxy:XCTestManager_IDEInterface:XCTestManager_DaemonConnectionInterface",
                "_IDE_initiateControlSessionWithProtocolVersion:", DTXServerRPCRawObj(XCODE_VERSION)).parsed
            logging.info("result: %s", result)
        ManagerdLockdown1.register_callback(DTXEnum.FINISHED, lambda _: self.quit_event.set())
        ManagerdLockdown1.register_unhandled_callback(_callback)

        ManagerdLockdown2 = TestManagerdLockdown(self.lockdown).init()
        ManagerdLockdown2._make_channel("dtxproxy:XCTestManager_IDEInterface:XCTestManager_DaemonConnectionInterface")
        ManagerdLockdown2.register_callback(DTXEnum.FINISHED, lambda _: self.quit_event.set())
        ManagerdLockdown2.register_unhandled_callback(_callback)

        _start_flag = threading.Event()

        def _start_executing(res=None):
            if _start_flag.is_set():
                return
            _start_flag.set()

            logging.info("Start execute test plan with IDE version: %d",
                         XCODE_VERSION)
            ManagerdLockdown2._call(False, 0xFFFFFFFF, '_IDE_startExecutingTestPlanWithProtocolVersion:',
                                    DTXServerRPCRawObj(XCODE_VERSION))

        def _show_log_message(res):
            logging.info(f"{res.parsed} : {get_auxiliary_text(res.raw)}")
            if 'Received test runner ready reply with error: (null' in ''.join(
                    get_auxiliary_text(res.raw)):
                logging.info("Test runner ready detected")
                _start_executing()

        ManagerdLockdown2.register_callback('_XCT_testBundleReadyWithProtocolVersion:minimumVersion:', _start_executing)
        ManagerdLockdown2.register_callback('_XCT_logDebugMessage:', _show_log_message)
        ManagerdLockdown2.register_callback('_XCT_didFinishExecutingTestPlan', lambda _: self.quit_event.set())

        result = ManagerdLockdown2.call('dtxproxy:XCTestManager_IDEInterface:XCTestManager_DaemonConnectionInterface',
                                        '_IDE_initiateSessionWithIdentifier:forClient:atPath:protocolVersion:',
                                        DTXServerRPCRawObj(
                                            session_identifier,
                                            str(session_identifier) + '-6722-000247F15966B083',
                                            '/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild',
                                            XCODE_VERSION
                                        )).parsed
        logging.info("result: %s", result)
        # launch_wda
        xctest_path = "/tmp/WebDriverAgentRunner-" + str(session_identifier).upper() + ".xctestconfiguration"
        xctest_content = archive(XCTestConfiguration({
            "testBundleURL": NSURL(None, "file://" + app_info['Path'] + "/PlugIns/WebDriverAgentRunner.xctest"),
            "sessionIdentifier": session_identifier,
        }))

        fsync = HouseArrestClient(self.lockdown)
        fsync.send_command(self.bundle_id)
        for fname in fsync.read_directory("/tmp"):
            if fname.endswith(".xctestconfiguration"):
                logging.debug("remove /tmp/%s", fname)
                fsync.file_remove("/tmp/" + fname)
        fsync.set_file_contents(xctest_path, xctest_content)

        conn = InstrumentServer(self.lockdown).init()
        conn.call('com.apple.instruments.server.services.processcontrol', 'processIdentifierForBundleIdentifier:',
                  self.bundle_id)

        conn.register_unhandled_callback(_callback)
        app_path = app_info['Path']
        app_container = app_info['Container']

        xctestconfiguration_path = app_container + xctest_path
        logging.info("AppPath: %s", app_path)
        logging.info("AppContainer: %s", app_container)

        app_env = {
            'CA_ASSERT_MAIN_THREAD_TRANSACTIONS': '0',
            'CA_DEBUG_TRANSACTIONS': '0',
            'DYLD_FRAMEWORK_PATH': app_path + '/Frameworks:',
            'DYLD_LIBRARY_PATH': app_path + '/Frameworks',
            'NSUnbufferedIO': 'YES',
            'SQLITE_ENABLE_THREAD_ASSERTIONS': '1',
            'WDA_PRODUCT_BUNDLE_IDENTIFIER': '',
            'XCTestConfigurationFilePath': xctestconfiguration_path,
            'XCODE_DBG_XPC_EXCLUSIONS': 'com.apple.dt.xctestSymbolicator',
            'MJPEG_SERVER_PORT': '',
            'USE_PORT': '',
        }
        if self.lockdown.ios_version > LooseVersion('11.0'):
            app_env['DYLD_INSERT_LIBRARIES'] = '/Developer/usr/lib/libMainThreadChecker.dylib'
            app_env['OS_ACTIVITY_DT_MODE'] = 'YES'
        app_options = {'StartSuspendedKey': False}
        if self.lockdown.ios_version > LooseVersion('12.0'):
            app_options['ActivateSuspended'] = True

        app_args = [
            '-NSTreatUnknownArgumentsAsOpen', 'NO',
            '-ApplePersistenceIgnoreState', 'YES'
        ]

        identifier = "launchSuspendedProcessWithDevicePath:bundleIdentifier:environment:arguments:options:"

        pid = conn.call('com.apple.instruments.server.services.processcontrol', identifier,
                        app_path, self.bundle_id, app_env, app_args, app_options).parsed
        if not isinstance(pid, int):
            logging.error(f"Launch failed: {pid}")
            raise Exception("Launch failed")

        logging.info(f"Launch {self.bundle_id} pid: {pid}")

        conn.call('com.apple.instruments.server.services.processcontrol', "startObservingPid:", DTXServerRPCRawObj(pid))

        if self.quit_event:
            conn.register_callback(DTXEnum.FINISHED, lambda _: self.quit_event.set())

        if self.lockdown.ios_version > LooseVersion('12.0'):
            identifier = '_IDE_authorizeTestSessionWithProcessID:'
            result = ManagerdLockdown1.call(
                'dtxproxy:XCTestManager_IDEInterface:XCTestManager_DaemonConnectionInterface',
                identifier,
                DTXServerRPCRawObj(pid)).parsed
            logging.info("_IDE_authorizeTestSessionWithProcessID: %s", result)
        else:
            identifier = '_IDE_initiateControlSessionForTestProcessID:protocolVersion:'
            result = ManagerdLockdown1.call(
                'dtxproxy:XCTestManager_IDEInterface:XCTestManager_DaemonConnectionInterface',
                identifier,
                DTXServerRPCRawObj(pid, XCODE_VERSION)).parsed
            logging.info("_IDE_authorizeTestSessionWithProcessID: %s", result)

        while not self.quit_event.wait(.1):
            pass
        logging.warning("xctrunner quited")
        conn.deinit()
        ManagerdLockdown2.deinit()
        ManagerdLockdown1.deinit()