|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * vim:expandtab:shiftwidth=2:tabstop=2:cin: |
|
3 * This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #include "nsLocalHandlerApp.h" |
|
8 #include "nsIURI.h" |
|
9 #include "nsIProcess.h" |
|
10 |
|
11 // XXX why does nsMIMEInfoImpl have a threadsafe nsISupports? do we need one |
|
12 // here too? |
|
13 NS_IMPL_ISUPPORTS(nsLocalHandlerApp, nsILocalHandlerApp, nsIHandlerApp) |
|
14 |
|
15 //////////////////////////////////////////////////////////////////////////////// |
|
16 //// nsIHandlerApp |
|
17 |
|
18 NS_IMETHODIMP nsLocalHandlerApp::GetName(nsAString& aName) |
|
19 { |
|
20 if (mName.IsEmpty() && mExecutable) { |
|
21 // Don't want to cache this, just in case someone resets the app |
|
22 // without changing the description.... |
|
23 mExecutable->GetLeafName(aName); |
|
24 } else { |
|
25 aName.Assign(mName); |
|
26 } |
|
27 |
|
28 return NS_OK; |
|
29 } |
|
30 |
|
31 NS_IMETHODIMP nsLocalHandlerApp::SetName(const nsAString & aName) |
|
32 { |
|
33 mName.Assign(aName); |
|
34 |
|
35 return NS_OK; |
|
36 } |
|
37 |
|
38 NS_IMETHODIMP |
|
39 nsLocalHandlerApp::SetDetailedDescription(const nsAString & aDescription) |
|
40 { |
|
41 mDetailedDescription.Assign(aDescription); |
|
42 |
|
43 return NS_OK; |
|
44 } |
|
45 |
|
46 NS_IMETHODIMP |
|
47 nsLocalHandlerApp::GetDetailedDescription(nsAString& aDescription) |
|
48 { |
|
49 aDescription.Assign(mDetailedDescription); |
|
50 |
|
51 return NS_OK; |
|
52 } |
|
53 |
|
54 NS_IMETHODIMP |
|
55 nsLocalHandlerApp::Equals(nsIHandlerApp *aHandlerApp, bool *_retval) |
|
56 { |
|
57 NS_ENSURE_ARG_POINTER(aHandlerApp); |
|
58 |
|
59 *_retval = false; |
|
60 |
|
61 // If the handler app isn't a local handler app, then it's not the same app. |
|
62 nsCOMPtr <nsILocalHandlerApp> localHandlerApp = do_QueryInterface(aHandlerApp); |
|
63 if (!localHandlerApp) |
|
64 return NS_OK; |
|
65 |
|
66 // If either handler app doesn't have an executable, then they aren't |
|
67 // the same app. |
|
68 nsCOMPtr<nsIFile> executable; |
|
69 nsresult rv = localHandlerApp->GetExecutable(getter_AddRefs(executable)); |
|
70 if (NS_FAILED(rv)) |
|
71 return rv; |
|
72 |
|
73 // Equality for two empty nsIHandlerApp |
|
74 if (!executable && !mExecutable) { |
|
75 *_retval = true; |
|
76 return NS_OK; |
|
77 } |
|
78 |
|
79 // At least one is set so they are not equal |
|
80 if (!mExecutable || !executable) |
|
81 return NS_OK; |
|
82 |
|
83 // Check the command line parameter list lengths |
|
84 uint32_t len; |
|
85 localHandlerApp->GetParameterCount(&len); |
|
86 if (mParameters.Length() != len) |
|
87 return NS_OK; |
|
88 |
|
89 // Check the command line params lists |
|
90 for (uint32_t idx = 0; idx < mParameters.Length(); idx++) { |
|
91 nsAutoString param; |
|
92 if (NS_FAILED(localHandlerApp->GetParameter(idx, param)) || |
|
93 !param.Equals(mParameters[idx])) |
|
94 return NS_OK; |
|
95 } |
|
96 |
|
97 return executable->Equals(mExecutable, _retval); |
|
98 } |
|
99 |
|
100 NS_IMETHODIMP |
|
101 nsLocalHandlerApp::LaunchWithURI(nsIURI *aURI, |
|
102 nsIInterfaceRequestor *aWindowContext) |
|
103 { |
|
104 // pass the entire URI to the handler. |
|
105 nsAutoCString spec; |
|
106 aURI->GetAsciiSpec(spec); |
|
107 return LaunchWithIProcess(spec); |
|
108 } |
|
109 |
|
110 nsresult |
|
111 nsLocalHandlerApp::LaunchWithIProcess(const nsCString& aArg) |
|
112 { |
|
113 nsresult rv; |
|
114 nsCOMPtr<nsIProcess> process = do_CreateInstance(NS_PROCESS_CONTRACTID, &rv); |
|
115 if (NS_FAILED(rv)) |
|
116 return rv; |
|
117 |
|
118 if (NS_FAILED(rv = process->Init(mExecutable))) |
|
119 return rv; |
|
120 |
|
121 const char *string = aArg.get(); |
|
122 |
|
123 return process->Run(false, &string, 1); |
|
124 } |
|
125 |
|
126 //////////////////////////////////////////////////////////////////////////////// |
|
127 //// nsILocalHandlerApp |
|
128 |
|
129 /* attribute nsIFile executable; */ |
|
130 NS_IMETHODIMP |
|
131 nsLocalHandlerApp::GetExecutable(nsIFile **aExecutable) |
|
132 { |
|
133 NS_IF_ADDREF(*aExecutable = mExecutable); |
|
134 return NS_OK; |
|
135 } |
|
136 |
|
137 NS_IMETHODIMP |
|
138 nsLocalHandlerApp::SetExecutable(nsIFile *aExecutable) |
|
139 { |
|
140 mExecutable = aExecutable; |
|
141 return NS_OK; |
|
142 } |
|
143 |
|
144 /* readonly attribute unsigned long parameterCount; */ |
|
145 NS_IMETHODIMP |
|
146 nsLocalHandlerApp::GetParameterCount(uint32_t *aParameterCount) |
|
147 { |
|
148 *aParameterCount = mParameters.Length(); |
|
149 return NS_OK; |
|
150 } |
|
151 |
|
152 /* void clearParameters (); */ |
|
153 NS_IMETHODIMP |
|
154 nsLocalHandlerApp::ClearParameters() |
|
155 { |
|
156 mParameters.Clear(); |
|
157 return NS_OK; |
|
158 } |
|
159 |
|
160 /* void appendParameter (in AString param); */ |
|
161 NS_IMETHODIMP |
|
162 nsLocalHandlerApp::AppendParameter(const nsAString & aParam) |
|
163 { |
|
164 mParameters.AppendElement(aParam); |
|
165 return NS_OK; |
|
166 } |
|
167 |
|
168 /* AString getParameter (in unsigned long parameterIndex); */ |
|
169 NS_IMETHODIMP |
|
170 nsLocalHandlerApp::GetParameter(uint32_t parameterIndex, nsAString & _retval) |
|
171 { |
|
172 if (mParameters.Length() <= parameterIndex) |
|
173 return NS_ERROR_INVALID_ARG; |
|
174 |
|
175 _retval.Assign(mParameters[parameterIndex]); |
|
176 return NS_OK; |
|
177 } |
|
178 |
|
179 /* boolean parameterExists (in AString param); */ |
|
180 NS_IMETHODIMP |
|
181 nsLocalHandlerApp::ParameterExists(const nsAString & aParam, bool *_retval) |
|
182 { |
|
183 *_retval = mParameters.Contains(aParam); |
|
184 return NS_OK; |
|
185 } |