|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #filter substitution |
|
6 |
|
7 const Cc = Components.classes; |
|
8 const Ci = Components.interfaces; |
|
9 const Cu = Components.utils; |
|
10 |
|
11 Cu.import("resource://gre/modules/FileUtils.jsm"); |
|
12 Cu.import("resource://gre/modules/Services.jsm"); |
|
13 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
14 |
|
15 // ----------------------------------------------------------------------- |
|
16 // Directory Provider for special browser folders and files |
|
17 // ----------------------------------------------------------------------- |
|
18 |
|
19 const NS_APP_CACHE_PARENT_DIR = "cachePDir"; |
|
20 const NS_APP_SEARCH_DIR = "SrchPlugns"; |
|
21 const NS_APP_SEARCH_DIR_LIST = "SrchPluginsDL"; |
|
22 const NS_APP_USER_SEARCH_DIR = "UsrSrchPlugns"; |
|
23 const NS_XPCOM_CURRENT_PROCESS_DIR = "XCurProcD"; |
|
24 const XRE_APP_DISTRIBUTION_DIR = "XREAppDist"; |
|
25 const XRE_UPDATE_ROOT_DIR = "UpdRootD"; |
|
26 const ENVVAR_UPDATE_DIR = "UPDATES_DIRECTORY"; |
|
27 const WEBAPPS_DIR = "webappsDir"; |
|
28 const DOWNLOAD_DIR = "DfltDwnld" |
|
29 |
|
30 const SYSTEM_DIST_PATH = "/system/@ANDROID_PACKAGE_NAME@/distribution"; |
|
31 |
|
32 function DirectoryProvider() {} |
|
33 |
|
34 DirectoryProvider.prototype = { |
|
35 classID: Components.ID("{ef0f7a87-c1ee-45a8-8d67-26f586e46a4b}"), |
|
36 |
|
37 QueryInterface: XPCOMUtils.generateQI([Ci.nsIDirectoryServiceProvider, |
|
38 Ci.nsIDirectoryServiceProvider2]), |
|
39 |
|
40 getFile: function(prop, persistent) { |
|
41 if (prop == NS_APP_CACHE_PARENT_DIR) { |
|
42 let dirsvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); |
|
43 let profile = dirsvc.get("ProfD", Ci.nsIFile); |
|
44 return profile; |
|
45 } else if (prop == WEBAPPS_DIR) { |
|
46 // returns the folder that should hold the webapps database file |
|
47 // For fennec we will store that in the root profile folder so that all |
|
48 // webapps can easily access it |
|
49 let dirsvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); |
|
50 let profile = dirsvc.get("ProfD", Ci.nsIFile); |
|
51 return profile.parent; |
|
52 } else if (prop == XRE_APP_DISTRIBUTION_DIR) { |
|
53 // First, check to see if there's a distribution in the data directory. |
|
54 let dataDist = FileUtils.getDir(NS_XPCOM_CURRENT_PROCESS_DIR, ["distribution"], false); |
|
55 if (!dataDist.exists()) { |
|
56 // Then check to see if there's distribution in the system directory. |
|
57 let systemDist = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); |
|
58 systemDist.initWithPath(SYSTEM_DIST_PATH); |
|
59 // Only return the system distribution location if it exists. |
|
60 if (systemDist.exists()) { |
|
61 return systemDist; |
|
62 } |
|
63 } |
|
64 return dataDist; |
|
65 } else if (prop == XRE_UPDATE_ROOT_DIR) { |
|
66 let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); |
|
67 if (env.exists(ENVVAR_UPDATE_DIR)) { |
|
68 let path = env.get(ENVVAR_UPDATE_DIR); |
|
69 if (path) { |
|
70 let localFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); |
|
71 localFile.initWithPath(path); |
|
72 return localFile; |
|
73 } |
|
74 } |
|
75 let dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager); |
|
76 return dm.defaultDownloadsDirectory; |
|
77 } else if (prop == DOWNLOAD_DIR) { |
|
78 let dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager); |
|
79 return dm.defaultDownloadsDirectory; |
|
80 } |
|
81 |
|
82 // We are retuning null to show failure instead for throwing an error. The |
|
83 // interface is called quite a bit and throwing an error is noisy. Returning |
|
84 // null works with the way the interface is called [see bug 529077] |
|
85 return null; |
|
86 }, |
|
87 |
|
88 /** |
|
89 * Appends the distribution-specific search engine directories to the array. |
|
90 * The distribution directory structure is as follows: |
|
91 * |
|
92 * \- distribution/ |
|
93 * \- searchplugins/ |
|
94 * |- common/ |
|
95 * \- locale/ |
|
96 * |- <locale 1>/ |
|
97 * ... |
|
98 * \- <locale N>/ |
|
99 * |
|
100 * Common engines are loaded for all locales. If there is no locale directory for |
|
101 * the current locale, there is a pref: "distribution.searchplugins.defaultLocale", |
|
102 * which specifies a default locale to use. |
|
103 */ |
|
104 _appendDistroSearchDirs: function(array) { |
|
105 let distro = this.getFile(XRE_APP_DISTRIBUTION_DIR); |
|
106 if (!distro.exists()) |
|
107 return; |
|
108 |
|
109 let searchPlugins = distro.clone(); |
|
110 searchPlugins.append("searchplugins"); |
|
111 if (!searchPlugins.exists()) |
|
112 return; |
|
113 |
|
114 let commonPlugins = searchPlugins.clone(); |
|
115 commonPlugins.append("common"); |
|
116 if (commonPlugins.exists()) |
|
117 array.push(commonPlugins); |
|
118 |
|
119 let localePlugins = searchPlugins.clone(); |
|
120 localePlugins.append("locale"); |
|
121 if (!localePlugins.exists()) |
|
122 return; |
|
123 |
|
124 let curLocale = Services.prefs.getCharPref("general.useragent.locale"); |
|
125 let curLocalePlugins = localePlugins.clone(); |
|
126 curLocalePlugins.append(curLocale); |
|
127 if (curLocalePlugins.exists()) { |
|
128 array.push(curLocalePlugins); |
|
129 return; |
|
130 } |
|
131 |
|
132 // We didn't append the locale dir - try the default one. |
|
133 let defLocale = Services.prefs.getCharPref("distribution.searchplugins.defaultLocale"); |
|
134 let defLocalePlugins = localePlugins.clone(); |
|
135 if (defLocalePlugins.exists()) |
|
136 array.push(defLocalePlugins); |
|
137 }, |
|
138 |
|
139 getFiles: function(prop) { |
|
140 if (prop != NS_APP_SEARCH_DIR_LIST) |
|
141 return; |
|
142 |
|
143 let result = []; |
|
144 |
|
145 /** |
|
146 * We want to preserve the following order, since the search service loads |
|
147 * engines in first-loaded-wins order. |
|
148 * - distro search plugin locations |
|
149 * - user search plugin locations (profile) |
|
150 * - app search plugin location (shipped engines) |
|
151 */ |
|
152 this._appendDistroSearchDirs(result); |
|
153 |
|
154 let appUserSearchDir = FileUtils.getDir(NS_APP_USER_SEARCH_DIR, [], false); |
|
155 if (appUserSearchDir.exists()) |
|
156 result.push(appUserSearchDir); |
|
157 |
|
158 let appSearchDir = FileUtils.getDir(NS_APP_SEARCH_DIR, [], false); |
|
159 if (appSearchDir.exists()) |
|
160 result.push(appSearchDir); |
|
161 |
|
162 return { |
|
163 QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]), |
|
164 hasMoreElements: function() { |
|
165 return result.length > 0; |
|
166 }, |
|
167 getNext: function() { |
|
168 return result.shift(); |
|
169 } |
|
170 }; |
|
171 } |
|
172 }; |
|
173 |
|
174 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DirectoryProvider]); |
|
175 |