コード例 #1
0
        //----------------------------------------------------------------------------
        // Construction
        //----------------------------------------------------------------------------

        public TrayApplicationContext()
            {
            this.disposed = false;
            InitializeComponent();
            this.statusText             = null;
            this.bugBotMessageQueue     = new SharedMemTaggedBlobQueue(false, TaggedBlob.BugBotMessageQueueUniquifier);
            this.bugBotCommandQueue     = new SharedMemTaggedBlobQueue(false, TaggedBlob.BugBotCommandQueueUniquifier);
            this.shutdownMonitor        = new ShutdownMonitor(Program.TrayUniquifier);
            this.shutdownMonitor.ShutdownEvent += (sender, e) => ShutdownApp();

            this.threadStarter = new HandshakeThreadStarter("Swerve Tray Notification Thread", this.NotificationThreadLoop);

            Application.ApplicationExit += (object sender, EventArgs e) => RemoveIcon();
            this.trayIcon.Visible = true;

            this.shutdownMonitor.StartMonitoring();
            StartBotBugNotificationThread();

            // Tell the service that we started
            try {
                this.bugBotCommandQueue.InitializeIfNecessary();
                this.bugBotCommandQueue.Write(new TaggedBlob(TaggedBlob.TagSwerveToolsTrayStarted, new byte[0]), 100);
                }
            catch (Exception)
                {
                // ignore
                }
            }
コード例 #2
0
ファイル: DeviceTracker.cs プロジェクト: SwerveRobotics/tools
 //---------------------------------------------------------------------------------------------
 // Construction
 // ---------------------------------------------------------------------------------------------
 public DeviceTracker(AndroidDebugBridge bridge)
 {
     this.bridge        = bridge;
     this.Devices       = new List<Device>();
     this.serverFailedConnects = 0;
     this.serverRestarts = 0;
     this.threadStarter = new HandshakeThreadStarter("Device List Monitor", DeviceTrackingThread);
 }
コード例 #3
0
 protected virtual void Dispose(bool notFinalizer)
 {
     if (!disposed)
     {
         this.disposed = true;
         if (notFinalizer)
         {
             lock (this)
             {
                 StopMonitoring();
             }
         }
         this.shutdownRequestedEvent?.Dispose();     this.shutdownRequestedEvent = null;
         this.threadStarter?.Dispose();              this.threadStarter          = null;
     }
 }
コード例 #4
0
 void ShutdownMonitorThread(HandshakeThreadStarter starter)
 {
     starter.DoHandshake();
     while (!starter.StopRequested)
     {
         try {
             this.shutdownRequestedEvent.WaitOne();
             this.ShutdownEvent?.Invoke(this, EventArgs.Empty);
             return;
         }
         catch (ThreadInterruptedException)
         {
             return;
         }
     }
 }
コード例 #5
0
ファイル: USBMonitor.cs プロジェクト: SwerveRobotics/tools
        //-----------------------------------------------------------------------------------------
        // Construction
        //-----------------------------------------------------------------------------------------

        public USBMonitor(IDeviceEvents eventRaiser, ITracer tracer, IntPtr notificationHandle, bool notificationHandleIsService)
            {
            this.eventRaiser                 = eventRaiser;
            this.tracer                      = tracer;
            this.notificationHandle          = notificationHandle;
            this.notificationHandleIsService = notificationHandleIsService;

            this.bugbotMessageQueue = new SharedMemTaggedBlobQueue(true, TaggedBlob.BugBotMessageQueueUniquifier);
            this.bugbotMessageQueue.InitializeIfNecessary();
            this.bugBotCommandQueue = new SharedMemTaggedBlobQueue(true, TaggedBlob.BugBotCommandQueueUniquifier);
            this.bugBotCommandQueue.InitializeIfNecessary();

            this.commandQueueStarter = new HandshakeThreadStarter("Command Q Listener", CommandQueueListenerThread);

            this.androidDeviceDatabase = new AndroidDeviceDatabase();

            UpdateStatusNoRememberedConnections();
            this.bugbotMessageQueue.Write(TaggedBlob.TagBugBotMessage, Resources.StartingMessage);

            this.deviceInterfacesOfInterest = new List<Guid>();
            this.deviceNotificationHandles  = new List<IntPtr>();

            this.started = false;
            }
コード例 #6
0
ファイル: USBMonitor.cs プロジェクト: SwerveRobotics/tools
        void CommandQueueListenerThread(HandshakeThreadStarter starter)
            {
            starter.DoHandshake();

            while (!starter.StopRequested)
                {
                List<TaggedBlob> blobs = this.bugBotCommandQueue.Read();
                foreach (TaggedBlob blob in blobs)
                    {
                    switch (blob.Tag)
                        {
                    case TaggedBlob.TagForgetLastConnection:
                        this.tracer.Trace($"TagForgetLastConnection command received");
                        ForgetLastTCPIPDevice();
                        break;
                    case TaggedBlob.TagSwerveToolsTrayStarted:
                        UpdateTrayStatus();
                        break;
                    case TaggedBlob.TagDisarmService:
                        this.armed = false;
                        NotifyDisarmed();
                        UpdateTrayStatus();
                        break;
                    case TaggedBlob.TagArmService:
                        this.armed = true;
                        NotifyArmed();
                        UpdateTrayStatus();
                        break;
                        }
                    }
                }
            }
コード例 #7
0
 protected virtual void Dispose(bool notFinalizer)
 {
     if (!disposed)
         {
         this.disposed = true;
         if (notFinalizer)
             {
             lock (this)
                 {
                 StopMonitoring();
                 }
             }
         this.shutdownRequestedEvent?.Dispose();     this.shutdownRequestedEvent = null;
         this.threadStarter?.Dispose();              this.threadStarter = null;
         }
 }
コード例 #8
0
 //----------------------------------------------------------------------------
 // Construction
 //----------------------------------------------------------------------------
 public ShutdownMonitor(string uniquifier)
 {
     this.shutdownRequestedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, Util.GlobalName("ShutDownMonitor", uniquifier, "Event"));
     this.threadStarter          = new HandshakeThreadStarter("ShutdownMonitorThread", ShutdownMonitorThread);
     this.disposed               = false;
 }
コード例 #9
0
 void ShutdownMonitorThread(HandshakeThreadStarter starter)
 {
     starter.DoHandshake();
     while (!starter.StopRequested)
         {
         try {
             this.shutdownRequestedEvent.WaitOne();
             this.ShutdownEvent?.Invoke(this, EventArgs.Empty) ;
             return;
             }
         catch (ThreadInterruptedException)
             {
             return;
             }
         }
 }
コード例 #10
0
ファイル: DeviceTracker.cs プロジェクト: SwerveRobotics/tools
        // RULE: Once a stop is requested, we NEVER create a new socket.
        // NOTE: With that rule in place, we probably could now get by w/o doing a handshake.
        //       The issue was that our (old) code here was racing with StopDeviceTrackign(), the
        //       former creating a socket and the latter closing it to wake us up. If that happened
        //       in the wrong order, we would never wake up.
        void DeviceTrackingThread(HandshakeThreadStarter starter)
        {
            Log.d(loggingTag, "::: DeviceTrackingThread started :::");

            // Right here we know that Start() hasn't yet returned. Do the interlock and let it return.
            starter.DoHandshake();

            // Loop until asked to stop. Do that even in the face of failures and exceptions
            while (!starter.StopRequested)
                {
                try
                    {
                    if (OpenSocketIfNecessary(starter))
                        {
                        // Opened a new socket. Ask the ADB server to give us device notifications
                        this.IsTrackingDevices = RequestDeviceNotifications();
                        }

                    if (this.IsTrackingDevices)
                        {
                        // read the length of the incoming message
                        int length = ReadLength(this.socketTrackDevices, new byte[4]);
                        if (length >= 0)
                            {
                            // read the incoming message
                            ProcessTrackingDevicesNotification(length);

                            // flag the fact that we have build the list at least once.
                            this.HasDeviceList = true;
                            }
                        }
                    }
                catch (Exception e)
                    {
                    Log.w(loggingTag, $"exception in DeviceTrackingThread: {e.Message}");
                    this.IsTrackingDevices = false;
                    CloseSocket(ref this.socketTrackDevices);
                    }
                }

            Log.d(loggingTag, "::: DeviceTrackingThread stopped :::");
        }
コード例 #11
0
ファイル: DeviceTracker.cs プロジェクト: SwerveRobotics/tools
 protected virtual void Dispose(bool notFromFinalizer)
 {
     if (!this.disposed)
         {
         this.disposed = true;
         if (notFromFinalizer)
             {
             }
         this.threadStarter?.Dispose();
         this.threadStarter = null;
         }
 }
コード例 #12
0
        void NotificationThreadLoop(HandshakeThreadStarter starter)
            {
            Trace(Program.LoggingTag, "===== NotificationThreadLoop start ... ");
            try {
                // Interlock with StartNotificationThread
                starter.DoHandshake();

                // Spin, waiting for kernel to make the section for us
                for (bool thrown = true; !starter.StopRequested && thrown; )
                    {
                    try {
                        thrown = false;
                        this.bugBotMessageQueue.InitializeIfNecessary();
                        }
                    catch (FileNotFoundException)
                        {
                        Trace(Program.LoggingTag, "service hasn't created shared mem");
                        thrown = true;
                        Thread.Sleep(2000);
                        }
                    catch (Exception e)
                        {
                        Trace(Program.LoggingTag, $"exception thrown: {e}");
                        }
                    }

                Trace(Program.LoggingTag, "===== NotificationThreadLoop listening");

                while (!starter.StopRequested)
                    {
                    try {
                        // Get messages from writer. This will block until there's
                        // (probably) messages for us to read
                        Trace(Program.LoggingTag, "waiting for message...");
                        List<TaggedBlob> messages = this.bugBotMessageQueue.Read();
                        Trace(Program.LoggingTag, "...messages received");
                        if (messages.Count > 0)
                            {
                            // Separate the messages with newlines.
                            StringBuilder balloonText = new StringBuilder();
                            foreach (TaggedBlob blob in messages)
                                {
                                switch (blob.Tag)
                                    {
                                case TaggedBlob.TagBugBotMessage:
                                    if (balloonText.Length > 0)
                                        balloonText.Append("\n");
                                    balloonText.Append(blob.Message);
                                    break;
                                case TaggedBlob.TagBugBotStatus:
                                    // Update the status text
                                    this.statusText = blob.Message;
                                    UpdateIconText();
                                    break;
                                    }
                                }

                            // Display them to the user
                            if (balloonText.Length > 0)
                                ShowBalloon(balloonText.ToString());
                            }
                        }
                    catch (ThreadInterruptedException)
                        {
                        return;
                        }
                    }
                }
            finally
                {
                Trace(Program.LoggingTag, "===== ... NotificationThreadLoop stop");
                }

            }
コード例 #13
0
 protected override void Dispose(bool notFinalizer)
     {
     if (!disposed)
         {
         this.disposed = true;
         if (notFinalizer)
             {
             // Called from user's code. Can / should cleanup managed objects
             StopBotBugNotificationThread();
             this.shutdownMonitor?.StopMonitoring();
             }
         // Called from finalizers (and user code). Avoid referencing other objects.
         this.trayIcon?.Dispose();           this.trayIcon = null;
         this.bugBotMessageQueue?.Dispose(); this.bugBotMessageQueue = null;
         this.bugBotCommandQueue?.Dispose(); this.bugBotCommandQueue = null;
         this.threadStarter?.Dispose();      this.threadStarter = null;
         }
     base.Dispose(notFinalizer);
     }
コード例 #14
0
ファイル: USBMonitor.cs プロジェクト: SwerveRobotics/tools
 protected virtual void Dispose(bool notFromFinalizer)
     {
     if (!disposed)
         {
         this.disposed = true;
         if (notFromFinalizer)
             {
             this.bugbotMessageQueue?.Write(TaggedBlob.TagBugBotMessage, Resources.StoppingMessage);
             }
         this.bugbotMessageQueue?.Dispose();     this.bugbotMessageQueue = null;
         this.bugBotCommandQueue?.Dispose();     this.bugBotCommandQueue = null;
         this.commandQueueStarter?.Dispose();    this.commandQueueStarter = null;
         this.ReleaseDeviceNotificationHandles();
         }
     }
コード例 #15
0
ファイル: DeviceTracker.cs プロジェクト: SwerveRobotics/tools
        // RULE: We NEVER create a new socket if a stop has been requested
        /**
         * Try, only once, to get a socket to the ADB server. If we can't connect, then
         * (perhaps) restart the server.
         *
         * @return  true if we opened a *new* socket
         */
        bool OpenSocketIfNecessary(HandshakeThreadStarter starter)
        {
            bool result = false;
            this.AcquireSocketLock();
            try
                {
                // If we haven't a socket, try to open one
                if (this.socketTrackDevices == null || !this.socketTrackDevices.Connected)
                    {
                    CloseSocket(ref this.socketTrackDevices);
                    this.socketTrackDevices = ConnectToServer();
                    //
                    if (this.socketTrackDevices == null)
                        {
                        // Connect attempt failed. Restart the server if we can
                        this.serverFailedConnects++;
                        if (this.serverFailedConnects > 0)
                            {
                            this.serverRestarts++;

                            if (starter.StopRequested) return result;
                            this.bridge.KillServer();               // takes seconds

                            if (starter.StopRequested) return result;
                            this.bridge.EnsureServerStarted();      // takes seconds

                            if (starter.StopRequested) return result;
                            }

                        if (this.serverRestarts > 1)
                            {
                            // Wait a bit before attempting another socket open
                            this.ReleaseSocketLock();
                            Log.d(loggingTag, "sleeping 1s");
                            Thread.Sleep(1000);
                            this.AcquireSocketLock();
                            }
                        }
                    else
                        {
                        result = true;
                        Log.d(loggingTag, "Connected to adb for device monitoring");
                        this.serverFailedConnects = 0;
                        this.serverRestarts = 0;
                        }
                    }
                }
            finally
                {
                this.ReleaseSocketLock();
                }
            return result;
        }
コード例 #16
0
        /**
         * Get the stderr/stdout outputs of a process and return when the process is done. Both
         * <b>must</b> be read or the process will block on windows.
         *
         * @exception   ArgumentNullException   Thrown when one or more required arguments are null.
         *
         * @param   process         The process to get the ouput from.
         * @param   errorOutput     The array to store the stderr output. cannot be null.
         * @param   stdOutput       The array to store the stdout output. cannot be null.
         * @param   waitforReaders  if true, this will wait for the reader threads.
         *
         * @return  the process return code.
         */
        private static int GrabProcessOutput(Process process, List<string> errorOutput, List<string> stdOutput, bool waitforReaders)
            {
            if (errorOutput == null)
                throw new ArgumentNullException(nameof(errorOutput));
            if (stdOutput == null)
                throw new ArgumentNullException(nameof(stdOutput));

            // read the lines as they come. if null is returned, it's
            // because the process finished
            HandshakeThreadStarter t1 = new HandshakeThreadStarter("StdErr reader", (starter) =>
                {
                // create a buffer to read the stdoutput
                try
                    {
                    using (StreamReader sr = process.StandardError)
                        {
                        starter.DoHandshake();

                        while (!starter.StopRequested && !sr.EndOfStream)
                            {
                            string line = sr.ReadLine();
                            if (!string.IsNullOrEmpty(line))
                                {
                                Log.e(ADB_EXE, line);
                                errorOutput.Add(line);
                                }
                            }
                        }
                    }
                catch (Exception)
                    {
                    // do nothing.
                    }
                });

            HandshakeThreadStarter t2 = new HandshakeThreadStarter("StdOut reader", (starter) =>
                {
                // create a buffer to read the std output
                try
                    {
                    using (StreamReader sr = process.StandardOutput)
                        {
                        starter.DoHandshake();

                        while (!starter.StopRequested && !sr.EndOfStream)
                            {
                            string line = sr.ReadLine();
                            if (!string.IsNullOrEmpty(line))
                                {
                                stdOutput.Add(line);
                                }
                            }
                        }
                    }
                catch (Exception)
                    {
                    // do nothing.
                    }
                });

            t1.Start();
            t2.Start();

            // it looks like on windows process#waitFor() can return
            // before the thread have filled the arrays, so we wait for both threads and the
            // process itself.
            if (waitforReaders)
                {
                try
                    {
                    t1.Join();
                    }
                catch (ThreadInterruptedException)
                    {
                    }
                try
                    {
                    t2.Join();
                    }
                catch (ThreadInterruptedException)
                    {
                    }
                }

            // get the return code from the process
            process.WaitForExit();
            return process.ExitCode;
            }
コード例 #17
0
        //----------------------------------------------------------------------------
        // Construction
        //----------------------------------------------------------------------------

        public ShutdownMonitor(string uniquifier)
        {
            this.shutdownRequestedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, Util.GlobalName("ShutDownMonitor", uniquifier, "Event"));
            this.threadStarter          = new HandshakeThreadStarter("ShutdownMonitorThread", ShutdownMonitorThread);
            this.disposed = false;
        }