private void OnPowerNotify(object sender, PowerManager.PowerEventArgs e) { PowerManager.PowerInfo powerInfo = e.PowerInfo; PrintLn( powerInfo.Message.ToString() + " " + powerInfo.Flags.ToString("X") + " " + GetSerialPortList() ); if (PowerManager.MessageTypes.Transition == powerInfo.Message) { // Ideally, we'd switch on the symbolic Flags enums, // but they don't cover all the observed values. switch ((uint)powerInfo.Flags) { case 0x00400000: // 0x00400000 is the lightest stage of power management, // probably corresponding to backlight off. It occurs // even when USB doesn't get powered down. // // However, we should react to it because it is always // the first thing our app sees when coming out of suspend. // Sometimes, waking is very slow, and the user will be confused // unless we trigger some feedback at the time of this first event. PrintStatus("Power interruption detected. Recalculating...", true); CloseReader(); break; case 0x00200000: // 0x00200000 == SystemPowerStates.Suspend PrintStatus("Suspend detected", true); SuspendTripped = true; TransitionsSinceSuspend = 0; break; case 0x10000000: // 0x00100000 == SystemPowerStates.Idle // Not sure why Idle is always observed *after* Suspend. // I thought Suspend was the deeper sleep state; e.g., // http://nicolasbesson.blogspot.com/2008/04/power-management-under-window-ce-part.html break; case 0x12010000: // 0x12010000 occurs when subsystems are powering up // ActiveSync is one of these subsystems, so we can't do // too much with this event, or we'll get false positives. // // The first 1201000 after Resume tends to correlate with the // FTDI serial port being back up, but not sure if order is guaranteed. // // There are usually 2 1201000 transitions after waking from resume. // There is a third one, several second later, when ActiveSync enables. TransitionsSinceSuspend += 1; PrintStatus("Detected " + TransitionsSinceSuspend + " transitions since suspend", true); if (SuspendTripped && (2 <= TransitionsSinceSuspend)) { if (null != rdr) { PrintStatus("Cleaning up reader connection...", true); CloseReader(); PrintStatus("Reopening reader...", true); OpenReader(); } SuspendTripped = false; } break; } } //switch (powerInfo.Message) //{ // case PowerManager.MessageTypes.Resume: // PrintLn("Resume Detected"); // NeedResumeRecovery = true; // break; // case PowerManager.MessageTypes.Transition: // if (NeedResumeRecovery) // { // // Reader's serial port becomes invalid during suspend // // Restore it here (if it was already open before suspend) // if (null != rdr) // { // PrintStatus("Reconnecting..."); // // See how much we can get away with // try // { // GetVersion(); // } // catch (Exception ex) // { // // We can catch the serial write exception here, but I'm not sure why. // // Isn't it supposed to happen in the GUI thread due to Invoke? // PrintLn("Caught Exception trying to use broken reader: " + ex.ToString()); // } // // Clean up old reader (to prevent SerialReader.Dispose method // // from trying to talk to it and throwing an exception somewhere // // we can't handle it. // PrintStatus("Cleaning up old reader..."); // PrintLn("Cleaning up old reader..."); // CloseReader(); // PrintStatus("Reopening reader..."); // PrintLn("Reopening reader..."); // OpenReader(); // PrintStatus("Connected"); // } // NeedResumeRecovery = false; // } // break; //} }
private void InitializePowerManager() { // Create a new instance of the PowerManager class pwrMngr = new PowerManager(); // Hook up the Power notify event. This event would not be activated // until EnableNotifications is called. pwrMngr.PowerNotify += new PowerManager.PowerEventHandler(OnPowerNotify); // Enable power notifications. This will cause a thread to start // that will fire the PowerNotify event when any power notification // is received. pwrMngr.EnableNotifications(); //// Get the current power state. //StringBuilder systemStateName = new StringBuilder(20); //PowerManager.SystemPowerStates systemState; //int nError = pwrMngr.GetSystemPowerState(systemStateName, out systemState); }