michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #filter substitution michael@0: michael@0: const Cc = Components.classes; michael@0: const Ci = Components.interfaces; michael@0: const Cu = Components.utils; michael@0: michael@0: Cu.import("resource://gre/modules/FileUtils.jsm"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: michael@0: // ----------------------------------------------------------------------- michael@0: // Directory Provider for special browser folders and files michael@0: // ----------------------------------------------------------------------- michael@0: michael@0: const NS_APP_CACHE_PARENT_DIR = "cachePDir"; michael@0: const NS_APP_SEARCH_DIR = "SrchPlugns"; michael@0: const NS_APP_SEARCH_DIR_LIST = "SrchPluginsDL"; michael@0: const NS_APP_USER_SEARCH_DIR = "UsrSrchPlugns"; michael@0: const NS_XPCOM_CURRENT_PROCESS_DIR = "XCurProcD"; michael@0: const XRE_APP_DISTRIBUTION_DIR = "XREAppDist"; michael@0: const XRE_UPDATE_ROOT_DIR = "UpdRootD"; michael@0: const ENVVAR_UPDATE_DIR = "UPDATES_DIRECTORY"; michael@0: const WEBAPPS_DIR = "webappsDir"; michael@0: const DOWNLOAD_DIR = "DfltDwnld" michael@0: michael@0: const SYSTEM_DIST_PATH = "/system/@ANDROID_PACKAGE_NAME@/distribution"; michael@0: michael@0: function DirectoryProvider() {} michael@0: michael@0: DirectoryProvider.prototype = { michael@0: classID: Components.ID("{ef0f7a87-c1ee-45a8-8d67-26f586e46a4b}"), michael@0: michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIDirectoryServiceProvider, michael@0: Ci.nsIDirectoryServiceProvider2]), michael@0: michael@0: getFile: function(prop, persistent) { michael@0: if (prop == NS_APP_CACHE_PARENT_DIR) { michael@0: let dirsvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); michael@0: let profile = dirsvc.get("ProfD", Ci.nsIFile); michael@0: return profile; michael@0: } else if (prop == WEBAPPS_DIR) { michael@0: // returns the folder that should hold the webapps database file michael@0: // For fennec we will store that in the root profile folder so that all michael@0: // webapps can easily access it michael@0: let dirsvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); michael@0: let profile = dirsvc.get("ProfD", Ci.nsIFile); michael@0: return profile.parent; michael@0: } else if (prop == XRE_APP_DISTRIBUTION_DIR) { michael@0: // First, check to see if there's a distribution in the data directory. michael@0: let dataDist = FileUtils.getDir(NS_XPCOM_CURRENT_PROCESS_DIR, ["distribution"], false); michael@0: if (!dataDist.exists()) { michael@0: // Then check to see if there's distribution in the system directory. michael@0: let systemDist = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); michael@0: systemDist.initWithPath(SYSTEM_DIST_PATH); michael@0: // Only return the system distribution location if it exists. michael@0: if (systemDist.exists()) { michael@0: return systemDist; michael@0: } michael@0: } michael@0: return dataDist; michael@0: } else if (prop == XRE_UPDATE_ROOT_DIR) { michael@0: let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); michael@0: if (env.exists(ENVVAR_UPDATE_DIR)) { michael@0: let path = env.get(ENVVAR_UPDATE_DIR); michael@0: if (path) { michael@0: let localFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); michael@0: localFile.initWithPath(path); michael@0: return localFile; michael@0: } michael@0: } michael@0: let dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager); michael@0: return dm.defaultDownloadsDirectory; michael@0: } else if (prop == DOWNLOAD_DIR) { michael@0: let dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager); michael@0: return dm.defaultDownloadsDirectory; michael@0: } michael@0: michael@0: // We are retuning null to show failure instead for throwing an error. The michael@0: // interface is called quite a bit and throwing an error is noisy. Returning michael@0: // null works with the way the interface is called [see bug 529077] michael@0: return null; michael@0: }, michael@0: michael@0: /** michael@0: * Appends the distribution-specific search engine directories to the array. michael@0: * The distribution directory structure is as follows: michael@0: * michael@0: * \- distribution/ michael@0: * \- searchplugins/ michael@0: * |- common/ michael@0: * \- locale/ michael@0: * |- / michael@0: * ... michael@0: * \- / michael@0: * michael@0: * Common engines are loaded for all locales. If there is no locale directory for michael@0: * the current locale, there is a pref: "distribution.searchplugins.defaultLocale", michael@0: * which specifies a default locale to use. michael@0: */ michael@0: _appendDistroSearchDirs: function(array) { michael@0: let distro = this.getFile(XRE_APP_DISTRIBUTION_DIR); michael@0: if (!distro.exists()) michael@0: return; michael@0: michael@0: let searchPlugins = distro.clone(); michael@0: searchPlugins.append("searchplugins"); michael@0: if (!searchPlugins.exists()) michael@0: return; michael@0: michael@0: let commonPlugins = searchPlugins.clone(); michael@0: commonPlugins.append("common"); michael@0: if (commonPlugins.exists()) michael@0: array.push(commonPlugins); michael@0: michael@0: let localePlugins = searchPlugins.clone(); michael@0: localePlugins.append("locale"); michael@0: if (!localePlugins.exists()) michael@0: return; michael@0: michael@0: let curLocale = Services.prefs.getCharPref("general.useragent.locale"); michael@0: let curLocalePlugins = localePlugins.clone(); michael@0: curLocalePlugins.append(curLocale); michael@0: if (curLocalePlugins.exists()) { michael@0: array.push(curLocalePlugins); michael@0: return; michael@0: } michael@0: michael@0: // We didn't append the locale dir - try the default one. michael@0: let defLocale = Services.prefs.getCharPref("distribution.searchplugins.defaultLocale"); michael@0: let defLocalePlugins = localePlugins.clone(); michael@0: if (defLocalePlugins.exists()) michael@0: array.push(defLocalePlugins); michael@0: }, michael@0: michael@0: getFiles: function(prop) { michael@0: if (prop != NS_APP_SEARCH_DIR_LIST) michael@0: return; michael@0: michael@0: let result = []; michael@0: michael@0: /** michael@0: * We want to preserve the following order, since the search service loads michael@0: * engines in first-loaded-wins order. michael@0: * - distro search plugin locations michael@0: * - user search plugin locations (profile) michael@0: * - app search plugin location (shipped engines) michael@0: */ michael@0: this._appendDistroSearchDirs(result); michael@0: michael@0: let appUserSearchDir = FileUtils.getDir(NS_APP_USER_SEARCH_DIR, [], false); michael@0: if (appUserSearchDir.exists()) michael@0: result.push(appUserSearchDir); michael@0: michael@0: let appSearchDir = FileUtils.getDir(NS_APP_SEARCH_DIR, [], false); michael@0: if (appSearchDir.exists()) michael@0: result.push(appSearchDir); michael@0: michael@0: return { michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]), michael@0: hasMoreElements: function() { michael@0: return result.length > 0; michael@0: }, michael@0: getNext: function() { michael@0: return result.shift(); michael@0: } michael@0: }; michael@0: } michael@0: }; michael@0: michael@0: this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DirectoryProvider]); michael@0: