summaryrefslogtreecommitdiffstats
path: root/uriloader/exthandler/nsMIMEInfoImpl.h
blob: 9b080ac5457cb8e27cc9814f4abfc1572590404e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=4 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __nsmimeinfoimpl_h___
#define __nsmimeinfoimpl_h___

#include "nsIMIMEInfo.h"
#include "nsAtom.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsIMutableArray.h"
#include "nsIFile.h"
#include "nsCOMPtr.h"
#include "nsIURI.h"
#include "nsIProcess.h"
#include "mozilla/dom/BrowsingContext.h"

/**
 * UTF8 moz-icon URI string for the default handler application's icon, if
 * available.
 */
#define PROPERTY_DEFAULT_APP_ICON_URL "defaultApplicationIconURL"
/**
 * UTF8 moz-icon URI string for the user's preferred handler application's
 * icon, if available.
 */
#define PROPERTY_CUSTOM_APP_ICON_URL "customApplicationIconURL"

/**
 * Basic implementation of nsIMIMEInfo. Incomplete - it is meant to be
 * subclassed, and GetHasDefaultHandler as well as LaunchDefaultWithFile need to
 * be implemented.
 */
class nsMIMEInfoBase : public nsIMIMEInfo {
 public:
  NS_DECL_THREADSAFE_ISUPPORTS

  // I'd use NS_DECL_NSIMIMEINFO, but I don't want GetHasDefaultHandler
  NS_IMETHOD GetFileExtensions(nsIUTF8StringEnumerator** _retval) override;
  NS_IMETHOD SetFileExtensions(const nsACString& aExtensions) override;
  NS_IMETHOD ExtensionExists(const nsACString& aExtension,
                             bool* _retval) override;
  NS_IMETHOD AppendExtension(const nsACString& aExtension) override;
  NS_IMETHOD GetPrimaryExtension(nsACString& aPrimaryExtension) override;
  NS_IMETHOD SetPrimaryExtension(const nsACString& aPrimaryExtension) override;
  NS_IMETHOD GetType(nsACString& aType) override;
  NS_IMETHOD GetMIMEType(nsACString& aMIMEType) override;
  NS_IMETHOD GetDescription(nsAString& aDescription) override;
  NS_IMETHOD SetDescription(const nsAString& aDescription) override;
  NS_IMETHOD Equals(nsIMIMEInfo* aMIMEInfo, bool* _retval) override;
  NS_IMETHOD GetPreferredApplicationHandler(
      nsIHandlerApp** aPreferredAppHandler) override;
  NS_IMETHOD SetPreferredApplicationHandler(
      nsIHandlerApp* aPreferredAppHandler) override;
  NS_IMETHOD GetPossibleApplicationHandlers(
      nsIMutableArray** aPossibleAppHandlers) override;
  NS_IMETHOD GetDefaultDescription(nsAString& aDefaultDescription) override;
  NS_IMETHOD LaunchWithFile(nsIFile* aFile) override;
  NS_IMETHOD LaunchWithURI(
      nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) override;
  NS_IMETHOD GetPreferredAction(nsHandlerInfoAction* aPreferredAction) override;
  NS_IMETHOD SetPreferredAction(nsHandlerInfoAction aPreferredAction) override;
  NS_IMETHOD GetAlwaysAskBeforeHandling(
      bool* aAlwaysAskBeforeHandling) override;
  NS_IMETHOD SetAlwaysAskBeforeHandling(bool aAlwaysAskBeforeHandling) override;
  NS_IMETHOD GetPossibleLocalHandlers(nsIArray** _retval) override;

  enum HandlerClass { eMIMEInfo, eProtocolInfo };

  // nsMIMEInfoBase methods
  explicit nsMIMEInfoBase(const char* aMIMEType = "");
  explicit nsMIMEInfoBase(const nsACString& aMIMEType);
  nsMIMEInfoBase(const nsACString& aType, HandlerClass aClass);

  void SetMIMEType(const nsACString& aMIMEType) { mSchemeOrType = aMIMEType; }

  void SetDefaultDescription(const nsString& aDesc) {
    mDefaultAppDescription = aDesc;
  }

  /**
   * Copies basic data of this MIME Info Implementation to the given other
   * MIME Info. The data consists of the MIME Type, the (default) description,
   * the MacOS type and creator, and the extension list (this object's
   * extension list will replace aOther's list, not append to it). This
   * function also ensures that aOther's primary extension will be the same as
   * the one of this object.
   */
  void CopyBasicDataTo(nsMIMEInfoBase* aOther);

  /**
   * Return whether this MIMEInfo has any extensions
   */
  bool HasExtensions() const { return mExtensions.Length() != 0; }

  static already_AddRefed<nsIFile> GetCanonicalExecutable(nsIFile* aFile);

 protected:
  virtual ~nsMIMEInfoBase();  // must be virtual, as the the base class's
                              // Release should call the subclass's destructor

  /**
   * Launch the default application for the given file.
   * For even more control over the launching, override launchWithFile.
   * Also see the comment about nsIMIMEInfo in general, above.
   *
   * @param aFile The file that should be opened
   */
  virtual nsresult LaunchDefaultWithFile(nsIFile* aFile) = 0;

  /**
   * Loads the URI with the OS default app.
   *
   * @param aURI The URI to pass off to the OS.
   */
  virtual nsresult LoadUriInternal(nsIURI* aURI) = 0;

  bool AutomationOnlyCheckIfLaunchStubbed(nsIFile* aFile);

  static already_AddRefed<nsIProcess> InitProcess(nsIFile* aApp,
                                                  nsresult* aResult);

  /**
   * This method can be used to launch the file or URI with a single
   * argument (typically either a file path or a URI spec).  This is
   * meant as a helper method for implementations of
   * LaunchWithURI/LaunchDefaultWithFile.
   *
   * @param aApp The application to launch (may not be null)
   * @param aArg The argument to pass on the command line
   */
  static nsresult LaunchWithIProcess(nsIFile* aApp, const nsCString& aArg);
  static nsresult LaunchWithIProcess(nsIFile* aApp, const nsString& aArg);
  static nsresult LaunchWithIProcess(nsIFile* aApp, const int aArgc,
                                     const char16_t** aArgv);

  /**
   * Given a file: nsIURI, return the associated nsIFile
   *
   * @param  aURI      the file: URI in question
   * @param  aFile     the associated nsIFile (out param)
   */
  static nsresult GetLocalFileFromURI(nsIURI* aURI, nsIFile** aFile);

  /**
   * Internal helper to avoid adding duplicates.
   */
  void AddUniqueExtension(const nsACString& aExtension);

  // member variables
  nsTArray<nsCString>
      mExtensions;  ///< array of file extensions associated w/ this MIME obj
  nsString mDescription;  ///< human readable description
  nsCString mSchemeOrType;
  HandlerClass mClass;
  nsCOMPtr<nsIHandlerApp> mPreferredApplication;
  nsCOMPtr<nsIMutableArray> mPossibleApplications;
  nsHandlerInfoAction mPreferredAction =
      nsIMIMEInfo::saveToDisk;  ///< preferred action to associate with this
                                ///< type
  nsString mPreferredAppDescription;
  nsString mDefaultAppDescription;
  bool mAlwaysAskBeforeHandling;
  bool mIsDefaultAppInfoFresh = false;
};

/**
 * This is a complete implementation of nsIMIMEInfo, and contains all necessary
 * methods. However, depending on your platform you may want to use a different
 * way of launching applications. This class stores the default application in a
 * member variable and provides a function for setting it. For local
 * applications, launching is done using nsIProcess, native path of the file to
 * open as first argument.
 */
class nsMIMEInfoImpl : public nsMIMEInfoBase {
 public:
  explicit nsMIMEInfoImpl(const char* aMIMEType = "")
      : nsMIMEInfoBase(aMIMEType) {}
  explicit nsMIMEInfoImpl(const nsACString& aMIMEType)
      : nsMIMEInfoBase(aMIMEType) {}
  nsMIMEInfoImpl(const nsACString& aType, HandlerClass aClass)
      : nsMIMEInfoBase(aType, aClass) {}
  virtual ~nsMIMEInfoImpl() {}

  // nsIMIMEInfo methods
  NS_IMETHOD GetHasDefaultHandler(bool* _retval) override;
  NS_IMETHOD GetDefaultDescription(nsAString& aDefaultDescription) override;
  NS_IMETHOD IsCurrentAppOSDefault(bool* _retval) override;

  // additional methods
  /**
   * Sets the default application. Supposed to be only called by the OS Helper
   * App Services.
   */
  void SetDefaultApplication(nsIFile* aApp) {
    mDefaultApplication = aApp;
    mIsDefaultAppInfoFresh = true;
  }

 protected:
  // nsMIMEInfoBase methods
  /**
   * The base class implementation is to use LaunchWithIProcess in combination
   * with mDefaultApplication. Subclasses can override that behaviour.
   */
  virtual nsresult LaunchDefaultWithFile(nsIFile* aFile) override;

  /**
   * Loads the URI with the OS default app.  This should be overridden by each
   * OS's implementation.
   */
  virtual nsresult LoadUriInternal(nsIURI* aURI) override = 0;

  // Accessor for default application for subclasses.
  nsIFile* GetDefaultApplication() { return mDefaultApplication; }

 private:
  nsCOMPtr<nsIFile>
      mDefaultApplication;  ///< default application associated with this type.
};

#endif  //__nsmimeinfoimpl_h___