Back to index

lightning-sunbird  0.9+nobinonly
nsPalmSyncSupport.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corp.
00018  * Portions created by the Initial Developer are Copyright (C) 2002
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s): 
00022  *           Rajiv Dayal <rdayal@netscape.com>
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #include "nsCOMPtr.h"
00038 #include "objbase.h"
00039 #include "nsISupports.h"
00040 
00041 #include "nsIGenericFactory.h"
00042 #include "nsIObserverService.h"
00043 #include "nsIAppStartupNotifier.h"
00044 #include "nsIServiceManager.h"
00045 #include "nsIComponentManager.h"
00046 #include "nsICategoryManager.h"
00047 #include "nsCRT.h"
00048 #ifdef MOZ_THUNDERBIRD
00049 #include "nsIExtensionManager.h"
00050 #endif
00051 #include "nsIFile.h"
00052 #include "nsILocalFile.h"
00053 #include "nsIPrefBranch.h"
00054 #include "nsIPrefService.h"
00055 
00056 #include "PalmSyncImp.h"
00057 #include "nsPalmSyncSupport.h"
00058 #include "Registry.h"
00059 #include <shellapi.h> // needed for ShellExecute
00060 
00061 #define EXTENSION_ID "p@m" // would ideally be palmsync@mozilla.org, but palm can't handle the long file path
00062 #define EXECUTABLE_FILENAME "PalmSyncInstall.exe"
00063 #define PREF_CONDUIT_REGISTERED "extensions.palmsync.conduitRegistered"
00064 
00065 
00074 NS_IMPL_THREADSAFE_ISUPPORTS2(nsPalmSyncSupport, nsIPalmSyncSupport, nsIObserver)
00075 
00076 static NS_METHOD nsPalmSyncRegistrationProc(nsIComponentManager *aCompMgr,
00077                    nsIFile *aPath, const char *registryLocation, const char *componentType,
00078                    const nsModuleComponentInfo *info)
00079 {  
00080     nsresult rv;
00081     nsCOMPtr<nsICategoryManager> categoryManager(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
00082     if (NS_SUCCEEDED(rv)) 
00083         rv = categoryManager->AddCategoryEntry(APPSTARTUP_CATEGORY, "PalmSync Support", 
00084                     "service," NS_IPALMSYNCSUPPORT_CONTRACTID, PR_TRUE, PR_TRUE, nsnull);
00085     return rv ;
00086 }
00087 
00088 static NS_METHOD nsPalmSyncUnRegistrationProc(nsIComponentManager *aCompMgr,
00089                    nsIFile *aPath, const char *registryLocation, const nsModuleComponentInfo *info)
00090 {    
00091     nsresult rv;
00092     nsCOMPtr<nsICategoryManager> categoryManager(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
00093     if (NS_SUCCEEDED(rv)) 
00094         rv = categoryManager->DeleteCategoryEntry(APPSTARTUP_CATEGORY, "PalmSync Support", PR_TRUE);
00095  
00096     return rv;
00097 }
00098 
00099 NS_IMETHODIMP
00100 nsPalmSyncSupport::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
00101 {
00102     nsresult rv = NS_OK ;
00103 
00104     // If nsIAppStartupNotifer tells us the app is starting up, then register
00105     // our observer topics and return.
00106     if (!strcmp(aTopic, "app-startup"))
00107     {
00108       nsCOMPtr<nsIObserverService> observerService(do_GetService("@mozilla.org/observer-service;1", &rv));
00109       NS_ENSURE_SUCCESS(rv, rv);
00110  
00111       rv = observerService->AddObserver(this,"profile-after-change", PR_FALSE);
00112       NS_ENSURE_SUCCESS(rv, rv);
00113 
00114       rv = observerService->AddObserver(this, "em-action-requested", PR_FALSE);
00115       NS_ENSURE_SUCCESS(rv, rv);      
00116 
00117       rv = observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
00118     }
00119     // otherwise, take the appropriate action based on the topic
00120     else if (!strcmp(aTopic, "profile-after-change"))
00121     {
00122 #ifdef MOZ_THUNDERBIRD
00123         // we can't call installPalmSync in app-startup because the extension manager hasn't been initialized yet. 
00124         // so we need to wait until the profile-after-change notification has fired. 
00125         rv = LaunchPalmSyncInstallExe(); 
00126 #endif
00127         rv |= InitializePalmSyncSupport();
00128     } 
00129     else if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID))
00130         rv = ShutdownPalmSyncSupport();
00131 #ifdef MOZ_THUNDERBIRD
00132     else if (aSubject && !strcmp(aTopic, "em-action-requested") && !nsCRT::strcmp(aData, NS_LITERAL_STRING("item-uninstalled").get()))
00133     {
00134         // make sure the subject is our extension.
00135         nsCOMPtr<nsIUpdateItem> updateItem (do_QueryInterface(aSubject, &rv));
00136         NS_ENSURE_SUCCESS(rv, rv);
00137 
00138         nsAutoString extensionName;
00139         updateItem->GetId(extensionName);
00140 
00141         if (extensionName.EqualsLiteral(EXTENSION_ID))
00142         {
00143             nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
00144             NS_ENSURE_SUCCESS(rv,rv);
00145            
00146             // clear the conduit pref so we'll re-run PalmSyncInstall.exe the next time the extension is installed.
00147             rv = prefBranch->ClearUserPref(PREF_CONDUIT_REGISTERED); 
00148 
00149             nsCOMPtr<nsILocalFile> palmSyncInstall;
00150             rv = GetPalmSyncInstall(getter_AddRefs(palmSyncInstall));
00151             NS_ENSURE_SUCCESS(rv, rv);
00152 
00153             nsCAutoString nativePath;
00154             palmSyncInstall->GetNativePath(nativePath);
00155         
00156             LONG r = (LONG) ::ShellExecuteA( NULL, NULL, nativePath.get(), "/u", NULL, SW_SHOWNORMAL);  // silent uninstall
00157         }
00158     }
00159 #endif
00160 
00161     return rv;
00162 }
00163 
00164 nsPalmSyncSupport::nsPalmSyncSupport()
00165 : m_dwRegister(0),
00166   m_nsPalmSyncFactory(nsnull)
00167 {
00168 }
00169 
00170 nsPalmSyncSupport::~nsPalmSyncSupport()
00171 {
00172 }
00173 
00174 #ifdef MOZ_THUNDERBIRD
00175 nsresult nsPalmSyncSupport::GetPalmSyncInstall(nsILocalFile ** aLocalFile)
00176 {
00177     nsresult rv;
00178     nsCOMPtr<nsIExtensionManager> em(do_GetService("@mozilla.org/extensions/manager;1"));
00179     NS_ENSURE_TRUE(em, NS_ERROR_FAILURE);
00180 
00181     nsCOMPtr<nsIInstallLocation> installLocation;
00182     rv = em->GetInstallLocation(NS_LITERAL_STRING(EXTENSION_ID), getter_AddRefs(installLocation));
00183     NS_ENSURE_SUCCESS(rv, rv);
00184 
00185     nsCOMPtr<nsIFile> palmSyncInstallExe;
00186     rv = installLocation->GetItemFile(NS_LITERAL_STRING(EXTENSION_ID), NS_LITERAL_STRING(EXECUTABLE_FILENAME), getter_AddRefs(palmSyncInstallExe));
00187     NS_ENSURE_SUCCESS(rv, rv);
00188 
00189     palmSyncInstallExe->QueryInterface(NS_GET_IID(nsILocalFile), (void **) aLocalFile);
00190     return rv;
00191 }
00192 
00193 nsresult nsPalmSyncSupport::LaunchPalmSyncInstallExe()
00194 {
00195     // we only want to call PalmSyncInstall.exe the first time the app is run after installing the
00196     // palm sync extension. We use PREF_CONDUIT_REGISTERED to keep track of that
00197     // information.
00198 
00199     nsresult rv;
00200     nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
00201     NS_ENSURE_SUCCESS(rv,rv);
00202     
00203     PRBool conduitIsRegistered = PR_FALSE;
00204     rv = prefBranch->GetBoolPref(PREF_CONDUIT_REGISTERED, &conduitIsRegistered);
00205     NS_ENSURE_SUCCESS(rv,rv);
00206 
00207     if (!conduitIsRegistered)
00208     {        
00209         rv = prefBranch->SetBoolPref(PREF_CONDUIT_REGISTERED, PR_TRUE); 
00210         nsCOMPtr<nsILocalFile> palmSyncInstall;
00211         rv = GetPalmSyncInstall(getter_AddRefs(palmSyncInstall));
00212         NS_ENSURE_SUCCESS(rv, rv);
00213 
00214         rv = palmSyncInstall->Launch();             
00215     }
00216 
00217     return rv;
00218 }
00219 #endif
00220 
00221 NS_IMETHODIMP
00222 nsPalmSyncSupport::InitializePalmSyncSupport()
00223 {
00224     ::CoInitialize(nsnull) ;
00225 
00226     if (m_nsPalmSyncFactory == nsnull)    // No Registering if already done.  Sanity Check!!
00227     {
00228         m_nsPalmSyncFactory = new CPalmSyncFactory();
00229 
00230         if (m_nsPalmSyncFactory != nsnull)
00231         {
00232             HRESULT hr = ::CoRegisterClassObject(CLSID_CPalmSyncImp, \
00233                                                  m_nsPalmSyncFactory, \
00234                                                  CLSCTX_LOCAL_SERVER, \
00235                                                  REGCLS_MULTIPLEUSE, \
00236                                                  &m_dwRegister);
00237 
00238             if (FAILED(hr))
00239             {
00240                 m_nsPalmSyncFactory->Release() ;
00241                 m_nsPalmSyncFactory = nsnull;
00242                 return NS_ERROR_FAILURE;
00243             }
00244            RegisterPalmSync();
00245         }
00246     }
00247 
00248     return NS_OK;
00249 }
00250 
00251 NS_IMETHODIMP
00252 nsPalmSyncSupport::ShutdownPalmSyncSupport()
00253 {
00254     if (m_dwRegister != 0)
00255         ::CoRevokeClassObject(m_dwRegister);
00256 
00257     if (m_nsPalmSyncFactory != nsnull)
00258     {
00259         m_nsPalmSyncFactory->Release();
00260         m_nsPalmSyncFactory = nsnull;
00261     }
00262 
00263     ::CoUninitialize();
00264 
00265     return NS_OK ;
00266 }
00267 
00268 NS_IMETHODIMP
00269 nsPalmSyncSupport::RegisterPalmSync()
00270 {
00271     return RegisterServerForPalmSync(CLSID_CPalmSyncImp, "Mozilla PalmSync", "MozillaPalmSync", "MozillaPalmSync.1");
00272 }
00273 
00274 NS_IMETHODIMP
00275 nsPalmSyncSupport::UnRegisterPalmSync()
00276 {
00277     return UnregisterServerForPalmSync(CLSID_CPalmSyncImp, "MozillaPalmSync", "MozillaPalmSync.1");
00278 }
00279 
00280 
00281 NS_GENERIC_FACTORY_CONSTRUCTOR(nsPalmSyncSupport)
00282 
00283 // The list of components we register
00284 static const nsModuleComponentInfo components[] = 
00285 {
00286     {
00287         NS_IPALMSYNCSUPPORT_CLASSNAME,
00288         NS_IPALMSYNCSUPPORT_CID,
00289         NS_IPALMSYNCSUPPORT_CONTRACTID,
00290         nsPalmSyncSupportConstructor,
00291         nsPalmSyncRegistrationProc,
00292         nsnull
00293     }
00294 };
00295 
00296 NS_IMPL_NSGETMODULE(PalmSyncModule, components)
00297