Example #1
0
        public async Task TryConnectAsync_NoMuxer_ReturnsNull_Async()
        {
            var client = new Mock <MuxerClient>();

            client.CallBase = true;
            var device = new MuxerDevice();

            client.Setup(c => c.TryConnectToMuxerAsync(default)).ReturnsAsync((MuxerProtocol)null);
Example #2
0
        public void ToString_ReturnsUdid()
        {
            var device = new MuxerDevice()
            {
                Udid = "abc",
            };

            Assert.Equal("abc", device.ToString());
        }
Example #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PairingRecordProvisionerTests"/> class.
        /// </summary>
        public PairingRecordProvisionerTests()
        {
            this.pairingWorker = new Mock <PairingWorker>(MockBehavior.Strict);
            this.kubernetesPairingRecordStore = new Mock <KubernetesPairingRecordStore>(MockBehavior.Strict);
            this.muxerClient    = new Mock <MuxerClient>(MockBehavior.Strict);
            this.lockdownClient = new Mock <LockdownClient>(MockBehavior.Strict);

            this.device = new MuxerDevice()
            {
                Udid = Udid
            };
            this.muxerClient.Setup(m => m.ListDevicesAsync(default)).ReturnsAsync(new Collection <MuxerDevice>()
Example #4
0
        public async Task ProvisionAsync_AlreadyMounted_DoesNothing_Async()
        {
            var store    = new Mock <DeveloperDiskStore>(MockBehavior.Strict);
            var provider = new Mock <DeviceServiceProvider>(MockBehavior.Strict);
            var device   = new MuxerDevice();

            var scope = new Mock <DeviceServiceScope>(MockBehavior.Strict);

            provider.Setup(p => p.CreateDeviceScopeAsync(device, default)).ReturnsAsync(scope.Object);

            var lockdown = new Mock <LockdownClient>(MockBehavior.Strict);
            var mounter  = new Mock <MobileImageMounterClient>(MockBehavior.Strict);

            scope.Setup(s => s.StartServiceAsync <LockdownClient>(default)).ReturnsAsync(lockdown.Object);
Example #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PairingWorkerTests"/> class.
        /// </summary>
        public PairingWorkerTests()
        {
            this.muxer = new Mock <MuxerClient>(MockBehavior.Strict);
            this.notificationProxyClient = new Mock <NotificationProxyClient>(MockBehavior.Strict);
            this.lockdown = new Mock <LockdownClient>(MockBehavior.Strict);
            this.device   = new MuxerDevice()
            {
                Udid = "my-udid"
            };
            this.pairingRecordGenerator = new Mock <PairingRecordGenerator>(MockBehavior.Strict);

            var lockdownFactory = new Mock <ClientFactory <LockdownClient> >(MockBehavior.Strict);

            lockdownFactory.Setup(f => f.CreateAsync(default)).ReturnsAsync(this.lockdown.Object);
Example #6
0
        /// <summary>
        /// Asynchronously create a device scope, which can be used to interact with services running on the iOS device.
        /// </summary>
        /// <param name="device">
        /// The device to which to connect.
        /// </param>
        /// <param name="cancellationToken">
        /// A <see cref="CancellationToken"/> which can be used to cancel the asynchronous operation.
        /// </param>
        /// <returns>
        /// A <see cref="Task"/> which represents the asynchronous operation, and returns a <see cref="IServiceScope"/>
        /// from which device services (such as lockdown service clients) can be sourced.
        /// </returns>
        public virtual async Task <DeviceServiceScope> CreateDeviceScopeAsync(MuxerDevice device, CancellationToken cancellationToken)
        {
            Requires.NotNull(device, nameof(device));

            var muxer = this.provider.GetRequiredService <MuxerClient>();
            var scope = this.provider.CreateScope();

            var context = scope.ServiceProvider.GetRequiredService <DeviceContext>();

            context.Device = device;

            context.PairingRecord = await muxer.ReadPairingRecordAsync(context.Device.Udid, cancellationToken).ConfigureAwait(false);

            return(new DeviceServiceScope(scope));
        }
Example #7
0
        /// <summary>
        /// Asynchronously mounts the developer disk on the device.
        /// </summary>
        /// <param name="device">
        /// The device on which to mount the developer disk.
        /// </param>
        /// <param name="cancellationToken">
        /// A <see cref="CancellationToken"/> which can be used to cancel the asynchronous operation.
        /// </param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation. The task returns a value indicating whether the developer disk
        /// is mounted on the device or not.
        /// </returns>
        public virtual async Task <bool> ProvisionDeveloperDiskAsync(MuxerDevice device, CancellationToken cancellationToken)
        {
            using (var scope = await this.serviceProvider.CreateDeviceScopeAsync(device, cancellationToken).ConfigureAwait(false))
                await using (var lockdown = await scope.StartServiceAsync <LockdownClient>(cancellationToken).ConfigureAwait(false))
                    await using (var imageMounterClient = await scope.StartServiceAsync <MobileImageMounterClient>(cancellationToken).ConfigureAwait(false))
                    {
                        var developerDiskStatus = await imageMounterClient.LookupImageAsync("Developer", cancellationToken).ConfigureAwait(false);

                        // The disk is already mounted.
                        if (developerDiskStatus.ImageSignature.Count > 0)
                        {
                            var signature = developerDiskStatus.ImageSignature.Count > 0 ? Convert.ToBase64String(developerDiskStatus.ImageSignature[0]) : string.Empty;

                            this.logger.LogWarning("A developer disk has already been mounted on device {udid}: {signature}", device.Udid, signature);
                            return(true);
                        }

                        // Fetch the disk from the store
                        var versionString = await lockdown.GetValueAsync("ProductVersion", cancellationToken).ConfigureAwait(false);

                        var version = Version.Parse(versionString);

                        var developerDisk = await this.developerDiskStore.GetAsync(version, cancellationToken).ConfigureAwait(false);

                        if (developerDisk == null && version.Build >= 0)
                        {
                            var reducedVersion = new Version(version.Major, version.Minor);
                            this.logger.LogWarning("Could not found the developer disk for version {version}. Attempting to find the developer disk for version {reducedVersion}", version, reducedVersion);
                            developerDisk = await this.developerDiskStore.GetAsync(reducedVersion, cancellationToken).ConfigureAwait(false);
                        }

                        if (developerDisk == null)
                        {
                            this.logger.LogWarning("Could not mount the developer disk on device {udid} because no developer disk is available", device.Udid);
                            return(false);
                        }

                        await imageMounterClient.UploadImageAsync(developerDisk.Image, "Developer", developerDisk.Signature, cancellationToken).ConfigureAwait(false);

                        await imageMounterClient.MountImageAsync(developerDisk.Signature, "Developer", cancellationToken).ConfigureAwait(false);

                        this.logger.LogInformation("Mounted the developer disk on device {udid}", device.Udid);

                        return(true);
                    }
        }
Example #8
0
        public async Task Connect_Works_Async()
        {
            // Sample traffic from https://www.theiphonewiki.com/wiki/Usbmux ("lockdownd protocol")
            var muxer  = new Mock <MuxerClient>();
            var device = new MuxerDevice();

            using (var traceStream = new TraceStream("Lockdown/connect-device.bin", "Lockdown/connect-host.bin"))
            {
                muxer
                .Setup(m => m.ConnectAsync(device, 0xF27E, default))
                .ReturnsAsync(traceStream);

                var factory = new LockdownClientFactory(muxer.Object, new DeviceContext()
                {
                    Device = device
                }, NullLogger <LockdownClient> .Instance);

                await using (await factory.CreateAsync(default))