OUT-17: Move adapter callbacks class into its own file. keysync
authorDean
Wed, 05 Oct 2016 12:36:19 +0200
branchkeysync
changeset 1344172fa144944e
parent 1343 1520e906a692
child 1346 77dbb54ed2b3
OUT-17: Move adapter callbacks class into its own file.
Also adds logging and other updates.
AdapterCallbacks.cs
ThisAddIn.cs
pEpForOutlook.csproj
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/AdapterCallbacks.cs	Wed Oct 05 12:36:19 2016 +0200
     1.3 @@ -0,0 +1,118 @@
     1.4 +´╗┐using pEp.UI;
     1.5 +using pEpCOMServerAdapterLib;
     1.6 +using System.Runtime.InteropServices;
     1.7 +using System.Windows.Forms;
     1.8 +using System;
     1.9 +
    1.10 +namespace pEp
    1.11 +{
    1.12 +    /// <summary>
    1.13 +    /// Callback implementation for the events the pEpEngine fires.
    1.14 +    /// </summary>
    1.15 +    /// <remarks>We need to have this in a class
    1.16 +    /// deriving from <see cref="StandardOleMarshalObject"/>, as this guarantees that the calls
    1.17 +    /// are scheduled on the primary thread. We're using a callback interface instead of events
    1.18 +    /// because it seems difficult to marshal complex datatypes (structs) for COM events, the
    1.19 +    /// default glue code generated by the VS wizard is not up to the task.
    1.20 +    /// </remarks>
    1.21 +    internal class AdapterCallbacks : StandardOleMarshalObject, IpEpEngineCallbacks
    1.22 +    {
    1.23 +        /// <summary>
    1.24 +        /// Event handler for when the pEp engine requests a handshake during key synchronization.
    1.25 +        /// </summary>
    1.26 +        /// <param name="own">The personal identity for the handshake.</param>
    1.27 +        /// <param name="partner">The communication partner identity for the handshake.</param>
    1.28 +        /// <returns>The user selected result.</returns>
    1.29 +        public SyncHandshakeResult ShowHandshake(ref pEpIdentity own,
    1.30 +                                                 ref pEpIdentity partner)
    1.31 +        {
    1.32 +            DialogResult dialogResult;
    1.33 +            SyncHandshakeResult hanshakeResult;
    1.34 +            FormHandshake handshakeDialog;
    1.35 +            FormControlHandshake.State state;
    1.36 +            PEPIdentity ownIdentity;
    1.37 +            PEPIdentity partnerIdentity;
    1.38 +
    1.39 +            Log.Verbose("ShowHandshake: Started");
    1.40 +
    1.41 +            // Ensure identities are updated with fingerprint
    1.42 +            ownIdentity = new PEPIdentity(ThisAddIn.PEPEngine.UpdateIdentity(own));
    1.43 +            partnerIdentity = new PEPIdentity(ThisAddIn.PEPEngine.UpdateIdentity(partner));
    1.44 +
    1.45 +            // Create settings
    1.46 +            state = new FormControlHandshake.State(ownIdentity,
    1.47 +                                                   partnerIdentity,
    1.48 +                                                   Globals.ThisAddIn.Settings.TrustwordsCulture);
    1.49 +            state.Mode = FormControlHandshake.State.HandshakeMode.KeySync;
    1.50 +
    1.51 +            // Show handshake dialog
    1.52 +            handshakeDialog = new FormHandshake();
    1.53 +            handshakeDialog.StartPosition = FormStartPosition.CenterParent;
    1.54 +            handshakeDialog.FormControl.DisplayState = state;
    1.55 +            dialogResult = handshakeDialog.ShowDialog();
    1.56 +
    1.57 +            // Send result back to the engine
    1.58 +            switch (dialogResult)
    1.59 +            {
    1.60 +                case DialogResult.Yes:
    1.61 +                    {
    1.62 +                        hanshakeResult = SyncHandshakeResult.SyncHandshakeAccepted;
    1.63 +                        break;
    1.64 +                    }
    1.65 +                case DialogResult.No:
    1.66 +                    {
    1.67 +                        hanshakeResult = SyncHandshakeResult.SyncHandshakeRejected;
    1.68 +                        break;
    1.69 +                    }
    1.70 +                case DialogResult.Cancel:
    1.71 +                default: // this should never happen if we cover all enums
    1.72 +                    {
    1.73 +                        hanshakeResult = SyncHandshakeResult.SyncHandshakeCancel;
    1.74 +                        break;
    1.75 +                    }
    1.76 +            }
    1.77 +
    1.78 +            Log.Verbose("ShowHandshake: Completed, " + hanshakeResult.ToString());
    1.79 +
    1.80 +            return (hanshakeResult);
    1.81 +        }
    1.82 +
    1.83 +        /// <summary>
    1.84 +        /// Event handler for when the pEp engine requests a message to be sent by the application.
    1.85 +        /// </summary>
    1.86 +        /// <param name="msg">The message to send.</param>
    1.87 +        public void MessageToSend(ref TextMessage msg)
    1.88 +        {
    1.89 +            PEPMessage newMessage;
    1.90 +
    1.91 +            Log.Verbose("MessageToSend: Started");
    1.92 +
    1.93 +            // This is an early prototype implementation.
    1.94 +            // Possible TODOs (which might require additional parameters down from the engine):
    1.95 +            // - Check whether the right account is used
    1.96 +            // - Enable sending "broadcast" to all accounts
    1.97 +
    1.98 +            var result = PEPMessage.Create(msg, out newMessage);
    1.99 +            if (result != Globals.ReturnStatus.Success)
   1.100 +            {
   1.101 +                // no need to log here, as PEPMessage.Create already logs the failure.
   1.102 +                Marshal.ThrowExceptionForHR(0xD /* ERROR_INVALID_DATA */ );
   1.103 +            }
   1.104 +
   1.105 +            // Now send the message
   1.106 +            try
   1.107 +            {
   1.108 +                Globals.ThisAddIn.SendWithoutProcessing(newMessage, false);
   1.109 +            }
   1.110 +            catch (Exception ex)
   1.111 +            {
   1.112 +                Log.Verbose("MessageToSend: Error trying to send message, " + ex.ToString());
   1.113 +                Marshal.ThrowExceptionForHR(0xD /* ERROR_INVALID_DATA */);
   1.114 +            }
   1.115 +
   1.116 +            Log.Verbose("MessageToSend: Completed");
   1.117 +
   1.118 +            return;
   1.119 +        }
   1.120 +    }
   1.121 +}
     2.1 --- a/ThisAddIn.cs	Tue Oct 04 23:01:22 2016 +0200
     2.2 +++ b/ThisAddIn.cs	Wed Oct 05 12:36:19 2016 +0200
     2.3 @@ -39,7 +39,7 @@
     2.4          private FormControlOptions.State   lastOptionsState   = null;
     2.5          private Dictionary<string, string> userIDCache        = new Dictionary<string, string>();
     2.6          private List<WatchedSentFolder>    watchedSentFolders = new List<WatchedSentFolder>();
     2.7 -        private CallbackImpl _callbackImpl;
     2.8 +        private AdapterCallbacks           adapterCallbacks;
     2.9  
    2.10          /**************************************************************
    2.11           * 
    2.12 @@ -2348,8 +2348,9 @@
    2.13                   */
    2.14                  if (this.initialized == false)
    2.15                  {
    2.16 -                    _callbackImpl = new CallbackImpl(this);
    2.17 -                    _PEPEngine.RegisterCallbacks(_callbackImpl);
    2.18 +                    // Connect callbacks, use PEPEngine property accessor incase the engine is not already initialized
    2.19 +                    this.adapterCallbacks = new AdapterCallbacks();
    2.20 +                    ThisAddIn.PEPEngine.RegisterCallbacks(this.adapterCallbacks);
    2.21  
    2.22                      this.RegisterMyself();
    2.23                      this.SetOutlookRegistryOptions();
    2.24 @@ -2429,11 +2430,13 @@
    2.25              this._Settings.SaveToRegistry();
    2.26              this._Settings.PropertyChanged -= Settings_PropertyChanged;
    2.27  
    2.28 -            // Release the pEp engine
    2.29              if (ThisAddIn._PEPEngine != null)
    2.30              {
    2.31 -                _PEPEngine.UnregisterCallbacks(_callbackImpl);
    2.32 -                _callbackImpl = null;
    2.33 +                // Disconnect callbacks, DO NOT use the PEPEngine property accessor (only use existing instance)
    2.34 +                ThisAddIn._PEPEngine.UnregisterCallbacks(this.adapterCallbacks);
    2.35 +                this.adapterCallbacks = null;
    2.36 +
    2.37 +                // Release the pEp engine
    2.38                  Marshal.FinalReleaseComObject(ThisAddIn._PEPEngine);
    2.39                  ThisAddIn._PEPEngine = null;
    2.40              }
    2.41 @@ -3022,92 +3025,5 @@
    2.42                  return;
    2.43              }
    2.44          }
    2.45 -
    2.46 -        /// <summary>
    2.47 -        /// Callback implementation for the events the pEpEngine fires.
    2.48 -        /// </summary>
    2.49 -        /// <remarks>We need to have this in a class
    2.50 -        /// deriving from <see cref="StandardOleMarshalObject"/>, as this guarantees that the calls
    2.51 -        /// are scheduled on the primary thread. We're using a callback interface instead of events
    2.52 -        /// because it seems difficult to marshal complex datatypes (structs) for COM events, the
    2.53 -        /// default glue code generated by the VS wizard is not up to the task.</remarks>
    2.54 -        private class CallbackImpl : StandardOleMarshalObject, IpEpEngineCallbacks
    2.55 -        {
    2.56 -            private readonly ThisAddIn _thisAddIn;
    2.57 -
    2.58 -            public CallbackImpl(ThisAddIn thisAddIn)
    2.59 -            {
    2.60 -                this._thisAddIn = thisAddIn;
    2.61 -            }
    2.62 -
    2.63 -            /// <summary>
    2.64 -            /// Event handler for when the pEp engine requests a handshake during key exchange.
    2.65 -            /// </summary>
    2.66 -            /// <param name="self">The personal identity for the handshake.</param>
    2.67 -            /// <param name="partner">The communication partner identity for the handshake.</param>
    2.68 -            /// 
    2.69 -            public SyncHandshakeResult ShowHandshake(ref pEpIdentity self,
    2.70 -                                                     ref pEpIdentity partner)
    2.71 -            {
    2.72 -                DialogResult result;
    2.73 -                FormHandshake handshakeDialog;
    2.74 -                FormControlHandshake.State state;
    2.75 -                PEPIdentity handshakeMyself;
    2.76 -                PEPIdentity handshakePartner;
    2.77 -
    2.78 -                // Ensure identities are updated with fingerprint
    2.79 -                handshakeMyself = new PEPIdentity(ThisAddIn.PEPEngine.UpdateIdentity(self));
    2.80 -                handshakePartner = new PEPIdentity(ThisAddIn.PEPEngine.UpdateIdentity(partner));
    2.81 -
    2.82 -                // Create settings
    2.83 -                state = new FormControlHandshake.State(handshakeMyself,
    2.84 -                                                       handshakePartner,
    2.85 -                                                       Globals.ThisAddIn.Settings.TrustwordsCulture);
    2.86 -                state.Mode = FormControlHandshake.State.HandshakeMode.KeySync;
    2.87 -
    2.88 -                // Show handshake dialog
    2.89 -                handshakeDialog = new FormHandshake();
    2.90 -                handshakeDialog.StartPosition = FormStartPosition.CenterParent;
    2.91 -                handshakeDialog.FormControl.DisplayState = state;
    2.92 -                result = handshakeDialog.ShowDialog();
    2.93 -
    2.94 -                // Send result back to the engine
    2.95 -                switch (result)
    2.96 -                {
    2.97 -                    case DialogResult.Yes:
    2.98 -                        {
    2.99 -                            return SyncHandshakeResult.SyncHandshakeAccepted;
   2.100 -                        }
   2.101 -                    case DialogResult.No:
   2.102 -                        {
   2.103 -                            return SyncHandshakeResult.SyncHandshakeRejected;
   2.104 -                        }
   2.105 -                    case DialogResult.Cancel:
   2.106 -                    default: // this should never happen if we cover all enums
   2.107 -                        {
   2.108 -                            return SyncHandshakeResult.SyncHandshakeCancel;
   2.109 -                        }
   2.110 -                }
   2.111 -            }
   2.112 -
   2.113 -            public void MessageToSend(ref TextMessage msg)
   2.114 -            {
   2.115 -                // This is an early prototype implementation.
   2.116 -                // Possible TODOs (which might require additional parameters down from the engine):
   2.117 -                // - Check whether the right account is used.
   2.118 -                // - Enable sending "broadcast" to all accounts.
   2.119 -
   2.120 -                PEPMessage ourMessage;
   2.121 -                var result = PEPMessage.Create(msg, out ourMessage);
   2.122 -                if (result != Globals.ReturnStatus.Success)
   2.123 -                {
   2.124 -                    // no need to log here, as PEPMessage.Create already logs the failure.
   2.125 -                    Marshal.ThrowExceptionForHR(0xD /* ERROR_INVALID_DATA */ );
   2.126 -                }
   2.127 -
   2.128 -                // Now send the message.
   2.129 -                _thisAddIn.SendWithoutProcessing(ourMessage, false);
   2.130 -            }
   2.131 -        }
   2.132      }
   2.133  }
     3.1 --- a/pEpForOutlook.csproj	Tue Oct 04 23:01:22 2016 +0200
     3.2 +++ b/pEpForOutlook.csproj	Wed Oct 05 12:36:19 2016 +0200
     3.3 @@ -273,6 +273,7 @@
     3.4      can be found.
     3.5    -->
     3.6    <ItemGroup>
     3.7 +    <Compile Include="AdapterCallbacks.cs" />
     3.8      <Compile Include="AdapterExtensions.cs" />
     3.9      <Compile Include="Comparisons.cs" />
    3.10      <Compile Include="ContactItemExtensions.cs" />