1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef mozilla_widget_WinUtils_h__
7 #define mozilla_widget_WinUtils_h__
8 
9 #include "nscore.h"
10 #include <windows.h>
11 #include <shobjidl.h>
12 #include <uxtheme.h>
13 #include <dwmapi.h>
14 
15 // Undo the windows.h damage
16 #undef GetMessage
17 #undef CreateEvent
18 #undef GetClassName
19 #undef GetBinaryType
20 #undef RemoveDirectory
21 
22 #include "nsString.h"
23 #include "nsRegion.h"
24 #include "nsRect.h"
25 
26 #include "nsIRunnable.h"
27 #include "nsICryptoHash.h"
28 #ifdef MOZ_PLACES
29 #include "nsIFaviconService.h"
30 #endif
31 #include "nsIDownloader.h"
32 #include "nsIURI.h"
33 #include "nsIWidget.h"
34 #include "nsIThread.h"
35 
36 #include "mozilla/Attributes.h"
37 #include "mozilla/EventForwards.h"
38 #include "mozilla/UniquePtr.h"
39 
40 /**
41  * NS_INLINE_DECL_IUNKNOWN_REFCOUNTING should be used for defining and
42  * implementing AddRef() and Release() of IUnknown interface.
43  * This depends on xpcom/glue/nsISupportsImpl.h.
44  */
45 
46 #define NS_INLINE_DECL_IUNKNOWN_REFCOUNTING(_class)                           \
47 public:                                                                       \
48   STDMETHODIMP_(ULONG) AddRef()                                               \
49   {                                                                           \
50     MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(_class)                                \
51     MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");                      \
52     NS_ASSERT_OWNINGTHREAD(_class);                                           \
53     ++mRefCnt;                                                                \
54     NS_LOG_ADDREF(this, mRefCnt, #_class, sizeof(*this));                     \
55     return static_cast<ULONG>(mRefCnt.get());                                 \
56   }                                                                           \
57   STDMETHODIMP_(ULONG) Release()                                              \
58   {                                                                           \
59     MOZ_ASSERT(int32_t(mRefCnt) > 0,                                          \
60       "Release called on object that has already been released!");            \
61     NS_ASSERT_OWNINGTHREAD(_class);                                           \
62     --mRefCnt;                                                                \
63     NS_LOG_RELEASE(this, mRefCnt, #_class);                                   \
64     if (mRefCnt == 0) {                                                       \
65       NS_ASSERT_OWNINGTHREAD(_class);                                         \
66       mRefCnt = 1; /* stabilize */                                            \
67       delete this;                                                            \
68       return 0;                                                               \
69     }                                                                         \
70     return static_cast<ULONG>(mRefCnt.get());                                 \
71   }                                                                           \
72 protected:                                                                    \
73   nsAutoRefCnt mRefCnt;                                                       \
74   NS_DECL_OWNINGTHREAD                                                        \
75 public:
76 
77 class nsWindow;
78 class nsWindowBase;
79 struct KeyPair;
80 
81 #if !defined(DPI_AWARENESS_CONTEXT_DECLARED) && !defined(DPI_AWARENESS_CONTEXT_UNAWARE)
82 
83 DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
84 
85 typedef enum DPI_AWARENESS {
86   DPI_AWARENESS_INVALID = -1,
87   DPI_AWARENESS_UNAWARE = 0,
88   DPI_AWARENESS_SYSTEM_AWARE = 1,
89   DPI_AWARENESS_PER_MONITOR_AWARE = 2
90 } DPI_AWARENESS;
91 
92 #define DPI_AWARENESS_CONTEXT_UNAWARE           ((DPI_AWARENESS_CONTEXT)-1)
93 #define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE      ((DPI_AWARENESS_CONTEXT)-2)
94 #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT)-3)
95 
96 #define DPI_AWARENESS_CONTEXT_DECLARED
97 #endif // (DPI_AWARENESS_CONTEXT_DECLARED)
98 
99 typedef DPI_AWARENESS_CONTEXT(WINAPI * SetThreadDpiAwarenessContextProc)(DPI_AWARENESS_CONTEXT);
100 typedef BOOL(WINAPI * EnableNonClientDpiScalingProc)(HWND);
101 
102 namespace mozilla {
103 namespace widget {
104 
105 // Windows message debugging data
106 typedef struct {
107   const char * mStr;
108   UINT         mId;
109 } EventMsgInfo;
110 extern EventMsgInfo gAllEvents[];
111 
112 // More complete QS definitions for MsgWaitForMultipleObjects() and
113 // GetQueueStatus() that include newer win8 specific defines.
114 
115 #ifndef QS_RAWINPUT
116 #define QS_RAWINPUT 0x0400
117 #endif
118 
119 #ifndef QS_TOUCH
120 #define QS_TOUCH    0x0800
121 #define QS_POINTER  0x1000
122 #endif
123 
124 #define MOZ_QS_ALLEVENT (QS_KEY | QS_MOUSEMOVE | QS_MOUSEBUTTON | \
125                          QS_POSTMESSAGE | QS_TIMER | QS_PAINT |   \
126                          QS_SENDMESSAGE | QS_HOTKEY |             \
127                          QS_ALLPOSTMESSAGE | QS_RAWINPUT |        \
128                          QS_TOUCH | QS_POINTER)
129 
130 // Logging macros
131 #define LogFunction() mozilla::widget::WinUtils::Log(__FUNCTION__)
132 #define LogThread() mozilla::widget::WinUtils::Log("%s: IsMainThread:%d ThreadId:%X", __FUNCTION__, NS_IsMainThread(), GetCurrentThreadId())
133 #define LogThis() mozilla::widget::WinUtils::Log("[%X] %s", this, __FUNCTION__)
134 #define LogException(e) mozilla::widget::WinUtils::Log("%s Exception:%s", __FUNCTION__, e->ToString()->Data())
135 #define LogHRESULT(hr) mozilla::widget::WinUtils::Log("%s hr=%X", __FUNCTION__, hr)
136 
137 #ifdef MOZ_PLACES
138 class myDownloadObserver final : public nsIDownloadObserver
139 {
~myDownloadObserver()140   ~myDownloadObserver() {}
141 
142 public:
143   NS_DECL_ISUPPORTS
144   NS_DECL_NSIDOWNLOADOBSERVER
145 };
146 #endif
147 
148 class WinUtils
149 {
150   // Function pointers for APIs that may not be available depending on
151   // the Win10 update version -- will be set up in Initialize().
152   static SetThreadDpiAwarenessContextProc sSetThreadDpiAwarenessContext;
153   static EnableNonClientDpiScalingProc sEnableNonClientDpiScaling;
154 
155 public:
156   class AutoSystemDpiAware
157   {
158   public:
AutoSystemDpiAware()159     AutoSystemDpiAware()
160     {
161       if (sSetThreadDpiAwarenessContext) {
162         mPrevContext = sSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
163       }
164     }
165 
~AutoSystemDpiAware()166     ~AutoSystemDpiAware()
167     {
168       if (sSetThreadDpiAwarenessContext) {
169         sSetThreadDpiAwarenessContext(mPrevContext);
170       }
171     }
172 
173   private:
174     DPI_AWARENESS_CONTEXT mPrevContext;
175   };
176 
177   // Wrapper for DefWindowProc that will enable non-client dpi scaling on the
178   // window during creation.
179   static LRESULT WINAPI
180   NonClientDpiScalingDefWindowProcW(HWND hWnd, UINT msg,
181                                     WPARAM wParam, LPARAM lParam);
182 
183   /**
184    * Get the system's default logical-to-physical DPI scaling factor,
185    * which is based on the primary display. Note however that unlike
186    * LogToPhysFactor(GetPrimaryMonitor()), this will not change during
187    * a session even if the displays are reconfigured. This scale factor
188    * is used by Windows theme metrics etc, which do not fully support
189    * dynamic resolution changes but are only updated on logout.
190    */
191   static double SystemScaleFactor();
192 
193   static bool IsPerMonitorDPIAware();
194   /**
195    * Functions to convert between logical pixels as used by most Windows APIs
196    * and physical (device) pixels.
197    */
198   static double LogToPhysFactor(HMONITOR aMonitor);
LogToPhysFactor(HWND aWnd)199   static double LogToPhysFactor(HWND aWnd) {
200     // if there's an ancestor window, we want to share its DPI setting
201     HWND ancestor = ::GetAncestor(aWnd, GA_ROOTOWNER);
202     return LogToPhysFactor(::MonitorFromWindow(ancestor ? ancestor : aWnd,
203                                                MONITOR_DEFAULTTOPRIMARY));
204   }
LogToPhysFactor(HDC aDC)205   static double LogToPhysFactor(HDC aDC) {
206     return LogToPhysFactor(::WindowFromDC(aDC));
207   }
208   static int32_t LogToPhys(HMONITOR aMonitor, double aValue);
209   static HMONITOR GetPrimaryMonitor();
210   static HMONITOR MonitorFromRect(const gfx::Rect& rect);
211 
212   /**
213    * Logging helpers that dump output to prlog module 'Widget', console, and
214    * OutputDebugString. Note these output in both debug and release builds.
215    */
216   static void Log(const char *fmt, ...);
217   static void LogW(const wchar_t *fmt, ...);
218 
219   /**
220    * PeekMessage() and GetMessage() are wrapper methods for PeekMessageW(),
221    * GetMessageW(), ITfMessageMgr::PeekMessageW() and
222    * ITfMessageMgr::GetMessageW().
223    * Don't call the native APIs directly.  You MUST use these methods instead.
224    */
225   static bool PeekMessage(LPMSG aMsg, HWND aWnd, UINT aFirstMessage,
226                           UINT aLastMessage, UINT aOption);
227   static bool GetMessage(LPMSG aMsg, HWND aWnd, UINT aFirstMessage,
228                          UINT aLastMessage);
229 
230   /**
231    * Wait until a message is ready to be processed.
232    * Prefer using this method to directly calling ::WaitMessage since
233    * ::WaitMessage will wait if there is an unread message in the queue.
234    * That can cause freezes until another message enters the queue if the
235    * message is marked read by a call to PeekMessage which the caller is
236    * not aware of (e.g., from a different thread).
237    * Note that this method may cause sync dispatch of sent (as opposed to
238    * posted) messages.
239    * @param aTimeoutMs Timeout for waiting in ms, defaults to INFINITE
240    */
241   static void WaitForMessage(DWORD aTimeoutMs = INFINITE);
242 
243   /**
244    * Gets the value of a string-typed registry value.
245    *
246    * @param aRoot The registry root to search in.
247    * @param aKeyName The name of the registry key to open.
248    * @param aValueName The name of the registry value in the specified key whose
249    *   value is to be retrieved.  Can be null, to retrieve the key's unnamed/
250    *   default value.
251    * @param aBuffer The buffer into which to store the string value.  Can be
252    *   null, in which case the return value indicates just whether the value
253    *   exists.
254    * @param aBufferLength The size of aBuffer, in bytes.
255    * @return Whether the value exists and is a string.
256    */
257   static bool GetRegistryKey(HKEY aRoot,
258                              char16ptr_t aKeyName,
259                              char16ptr_t aValueName,
260                              wchar_t* aBuffer,
261                              DWORD aBufferLength);
262 
263   /**
264    * Checks whether the registry key exists in either 32bit or 64bit branch on
265    * the environment.
266    *
267    * @param aRoot The registry root of aName.
268    * @param aKeyName The name of the registry key to check.
269    * @return TRUE if it exists and is readable.  Otherwise, FALSE.
270    */
271   static bool HasRegistryKey(HKEY aRoot,
272                              char16ptr_t aKeyName);
273 
274   /**
275    * GetTopLevelHWND() returns a window handle of the top level window which
276    * aWnd belongs to.  Note that the result may not be our window, i.e., it
277    * may not be managed by nsWindow.
278    *
279    * See follwing table for the detail of the result window type.
280    *
281    * +-------------------------+-----------------------------------------------+
282    * |                         |                aStopIfNotPopup                |
283    * +-------------------------+-----------------------+-----------------------+
284    * |                         |         TRUE          |         FALSE         |
285    + +-----------------+-------+-----------------------+-----------------------+
286    * |                 |       |  * an independent top level window            |
287    * |                 | TRUE  |  * a pupup window (WS_POPUP)                  |
288    * |                 |       |  * an owned top level window (like dialog)    |
289    * | aStopIfNotChild +-------+-----------------------+-----------------------+
290    * |                 |       |  * independent window | * only an independent |
291    * |                 | FALSE |  * non-popup-owned-   |   top level window    |
292    * |                 |       |    window like dialog |                       |
293    * +-----------------+-------+-----------------------+-----------------------+
294    */
295   static HWND GetTopLevelHWND(HWND aWnd,
296                               bool aStopIfNotChild = false,
297                               bool aStopIfNotPopup = true);
298 
299   /**
300    * SetNSWindowBasePtr() associates an nsWindowBase to aWnd.  If aWidget is
301    * nullptr, it dissociate any nsBaseWidget pointer from aWnd.
302    * GetNSWindowBasePtr() returns an nsWindowBase pointer which was associated by
303    * SetNSWindowBasePtr().
304    * GetNSWindowPtr() is a legacy api for win32 nsWindow and should be avoided
305    * outside of nsWindow src.
306    */
307   static bool SetNSWindowBasePtr(HWND aWnd, nsWindowBase* aWidget);
308   static nsWindowBase* GetNSWindowBasePtr(HWND aWnd);
309   static nsWindow* GetNSWindowPtr(HWND aWnd);
310 
311   /**
312    * GetMonitorCount() returns count of monitors on the environment.
313    */
314   static int32_t GetMonitorCount();
315 
316   /**
317    * IsOurProcessWindow() returns TRUE if aWnd belongs our process.
318    * Otherwise, FALSE.
319    */
320   static bool IsOurProcessWindow(HWND aWnd);
321 
322   /**
323    * FindOurProcessWindow() returns the nearest ancestor window which
324    * belongs to our process.  If it fails to find our process's window by the
325    * top level window, returns nullptr.  And note that this is using
326    * ::GetParent() for climbing the window hierarchy, therefore, it gives
327    * up at an owned top level window except popup window (e.g., dialog).
328    */
329   static HWND FindOurProcessWindow(HWND aWnd);
330 
331   /**
332    * FindOurWindowAtPoint() returns the topmost child window which belongs to
333    * our process's top level window.
334    *
335    * NOTE: the topmost child window may NOT be our process's window like a
336    *       plugin's window.
337    */
338   static HWND FindOurWindowAtPoint(const POINT& aPointInScreen);
339 
340   /**
341    * InitMSG() returns an MSG struct which was initialized by the params.
342    * Don't trust the other members in the result.
343    */
344   static MSG InitMSG(UINT aMessage, WPARAM wParam, LPARAM lParam, HWND aWnd);
345 
346   /**
347    * GetScanCode() returns a scan code for the LPARAM of WM_KEYDOWN, WM_KEYUP,
348    * WM_CHAR and WM_UNICHAR.
349    *
350    */
GetScanCode(LPARAM aLParam)351   static WORD GetScanCode(LPARAM aLParam)
352   {
353     return (aLParam >> 16) & 0xFF;
354   }
355 
356   /**
357    * IsExtendedScanCode() returns TRUE if the LPARAM indicates the key message
358    * is an extended key event.
359    */
IsExtendedScanCode(LPARAM aLParam)360   static bool IsExtendedScanCode(LPARAM aLParam)
361   {
362     return (aLParam & 0x1000000) != 0;
363   }
364 
365   /**
366    * GetInternalMessage() converts a native message to an internal message.
367    * If there is no internal message for the given native message, returns
368    * the native message itself.
369    */
370   static UINT GetInternalMessage(UINT aNativeMessage);
371 
372   /**
373    * GetNativeMessage() converts an internal message to a native message.
374    * If aInternalMessage is a native message, returns the native message itself.
375    */
376   static UINT GetNativeMessage(UINT aInternalMessage);
377 
378   /**
379    * GetMouseInputSource() returns a pointing device information.  The value is
380    * one of nsIDOMMouseEvent::MOZ_SOURCE_*.  This method MUST be called during
381    * mouse message handling.
382    */
383   static uint16_t GetMouseInputSource();
384 
385   /**
386    * Windows also fires mouse window messages for pens and touches, so we should
387    * retrieve their pointer ID on receiving mouse events as well. Please refer to
388    * https://msdn.microsoft.com/en-us/library/windows/desktop/ms703320(v=vs.85).aspx
389    */
390   static uint16_t GetMousePointerID();
391 
392   static bool GetIsMouseFromTouch(EventMessage aEventType);
393 
394   /**
395    * SHCreateItemFromParsingName() calls native SHCreateItemFromParsingName()
396    * API which is available on Vista and up.
397    */
398   static HRESULT SHCreateItemFromParsingName(PCWSTR pszPath, IBindCtx *pbc,
399                                              REFIID riid, void **ppv);
400 
401   /**
402    * SHGetKnownFolderPath() calls native SHGetKnownFolderPath()
403    * API which is available on Vista and up.
404    */
405   static HRESULT SHGetKnownFolderPath(REFKNOWNFOLDERID rfid,
406                                       DWORD dwFlags,
407                                       HANDLE hToken,
408                                       PWSTR *ppszPath);
409   /**
410    * GetShellItemPath return the file or directory path of a shell item.
411    * Internally calls IShellItem's GetDisplayName.
412    *
413    * aItem  the shell item containing the path.
414    * aResultString  the resulting string path.
415    * returns  true if a path was retreived.
416    */
417   static bool GetShellItemPath(IShellItem* aItem,
418                                nsString& aResultString);
419 
420   /**
421    * ConvertHRGNToRegion converts a Windows HRGN to an nsIntRegion.
422    *
423    * aRgn the HRGN to convert.
424    * returns the nsIntRegion.
425    */
426   static nsIntRegion ConvertHRGNToRegion(HRGN aRgn);
427 
428   /**
429    * ToIntRect converts a Windows RECT to a nsIntRect.
430    *
431    * aRect the RECT to convert.
432    * returns the nsIntRect.
433    */
434   static nsIntRect ToIntRect(const RECT& aRect);
435 
436   /**
437    * Helper used in invalidating flash plugin windows owned
438    * by low rights flash containers.
439    */
440   static void InvalidatePluginAsWorkaround(nsIWidget* aWidget,
441                                            const LayoutDeviceIntRect& aRect);
442 
443   /**
444    * Returns true if the context or IME state is enabled.  Otherwise, false.
445    */
446   static bool IsIMEEnabled(const InputContext& aInputContext);
447   static bool IsIMEEnabled(IMEState::Enabled aIMEState);
448 
449   /**
450    * Returns modifier key array for aModifiers.  This is for
451    * nsIWidget::SynthethizeNative*Event().
452    */
453   static void SetupKeyModifiersSequence(nsTArray<KeyPair>* aArray,
454                                         uint32_t aModifiers);
455 
456   /**
457   * Does device have touch support
458   */
459   static uint32_t IsTouchDeviceSupportPresent();
460 
461   /**
462   * The maximum number of simultaneous touch contacts supported by the device.
463   * In the case of devices with multiple digitizers (e.g. multiple touch screens),
464   * the value will be the maximum of the set of maximum supported contacts by
465   * each individual digitizer.
466   */
467   static uint32_t GetMaxTouchPoints();
468 
469   /**
470    * Fully resolves a path to its final path name. So if path contains
471    * junction points or symlinks to other folders, we'll resolve the path
472    * fully to the actual path that the links target.
473    *
474    * @param aPath path to be resolved.
475    * @return true if successful, including if nothing needs to be changed.
476    *         false if something failed or aPath does not exist, aPath will
477    *               remain unchanged.
478    */
479   static bool ResolveJunctionPointsAndSymLinks(std::wstring& aPath);
480 
481   /**
482   * dwmapi.dll function typedefs and declarations
483   */
484   typedef HRESULT (WINAPI*DwmExtendFrameIntoClientAreaProc)(HWND hWnd, const MARGINS *pMarInset);
485   typedef HRESULT (WINAPI*DwmIsCompositionEnabledProc)(BOOL *pfEnabled);
486   typedef HRESULT (WINAPI*DwmSetIconicThumbnailProc)(HWND hWnd, HBITMAP hBitmap, DWORD dwSITFlags);
487   typedef HRESULT (WINAPI*DwmSetIconicLivePreviewBitmapProc)(HWND hWnd, HBITMAP hBitmap, POINT *pptClient, DWORD dwSITFlags);
488   typedef HRESULT (WINAPI*DwmGetWindowAttributeProc)(HWND hWnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
489   typedef HRESULT (WINAPI*DwmSetWindowAttributeProc)(HWND hWnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
490   typedef HRESULT (WINAPI*DwmInvalidateIconicBitmapsProc)(HWND hWnd);
491   typedef HRESULT (WINAPI*DwmDefWindowProcProc)(HWND hWnd, UINT msg, LPARAM lParam, WPARAM wParam, LRESULT *aRetValue);
492   typedef HRESULT (WINAPI*DwmGetCompositionTimingInfoProc)(HWND hWnd, DWM_TIMING_INFO *info);
493   typedef HRESULT (WINAPI*DwmFlushProc)(void);
494 
495   static DwmExtendFrameIntoClientAreaProc dwmExtendFrameIntoClientAreaPtr;
496   static DwmIsCompositionEnabledProc dwmIsCompositionEnabledPtr;
497   static DwmSetIconicThumbnailProc dwmSetIconicThumbnailPtr;
498   static DwmSetIconicLivePreviewBitmapProc dwmSetIconicLivePreviewBitmapPtr;
499   static DwmGetWindowAttributeProc dwmGetWindowAttributePtr;
500   static DwmSetWindowAttributeProc dwmSetWindowAttributePtr;
501   static DwmInvalidateIconicBitmapsProc dwmInvalidateIconicBitmapsPtr;
502   static DwmDefWindowProcProc dwmDwmDefWindowProcPtr;
503   static DwmGetCompositionTimingInfoProc dwmGetCompositionTimingInfoPtr;
504   static DwmFlushProc dwmFlushProcPtr;
505 
506   static void Initialize();
507 
508   static bool ShouldHideScrollbars();
509 
510   /**
511    * This function normalizes the input path, converts short filenames to long
512    * filenames, and substitutes environment variables for system paths.
513    * The resulting output string length is guaranteed to be <= MAX_PATH.
514    */
515   static bool SanitizePath(const wchar_t* aInputPath, nsAString& aOutput);
516 
517   /**
518    * Retrieve a semicolon-delimited list of DLL files derived from AppInit_DLLs
519    */
520   static bool GetAppInitDLLs(nsAString& aOutput);
521 
522 #ifdef ACCESSIBILITY
523   static void SetAPCPending();
524 #endif
525 
526 private:
527   typedef HRESULT (WINAPI * SHCreateItemFromParsingNamePtr)(PCWSTR pszPath,
528                                                             IBindCtx *pbc,
529                                                             REFIID riid,
530                                                             void **ppv);
531   static SHCreateItemFromParsingNamePtr sCreateItemFromParsingName;
532   typedef HRESULT (WINAPI * SHGetKnownFolderPathPtr)(REFKNOWNFOLDERID rfid,
533                                                      DWORD dwFlags,
534                                                      HANDLE hToken,
535                                                      PWSTR *ppszPath);
536   static SHGetKnownFolderPathPtr sGetKnownFolderPath;
537 
538   static void GetWhitelistedPaths(
539       nsTArray<mozilla::Pair<nsString,nsDependentString>>& aOutput);
540 };
541 
542 #ifdef MOZ_PLACES
543 class AsyncFaviconDataReady final : public nsIFaviconDataCallback
544 {
545 public:
546   NS_DECL_ISUPPORTS
547   NS_DECL_NSIFAVICONDATACALLBACK
548 
549   AsyncFaviconDataReady(nsIURI *aNewURI,
550                         nsCOMPtr<nsIThread> &aIOThread,
551                         const bool aURLShortcut);
552   nsresult OnFaviconDataNotAvailable(void);
553 private:
~AsyncFaviconDataReady()554   ~AsyncFaviconDataReady() {}
555 
556   nsCOMPtr<nsIURI> mNewURI;
557   nsCOMPtr<nsIThread> mIOThread;
558   const bool mURLShortcut;
559 };
560 #endif
561 
562 /**
563   * Asynchronously tries add the list to the build
564   */
565 class AsyncEncodeAndWriteIcon : public nsIRunnable
566 {
567 public:
568   const bool mURLShortcut;
569   NS_DECL_THREADSAFE_ISUPPORTS
570   NS_DECL_NSIRUNNABLE
571 
572   // Warning: AsyncEncodeAndWriteIcon assumes ownership of the aData buffer passed in
573   AsyncEncodeAndWriteIcon(const nsAString &aIconPath,
574                           UniquePtr<uint8_t[]> aData,
575                           uint32_t aStride, uint32_t aWidth, uint32_t aHeight,
576                           const bool aURLShortcut);
577 
578 private:
579   virtual ~AsyncEncodeAndWriteIcon();
580 
581   nsAutoString mIconPath;
582   UniquePtr<uint8_t[]> mBuffer;
583   uint32_t mStride;
584   uint32_t mWidth;
585   uint32_t mHeight;
586 };
587 
588 
589 class AsyncDeleteIconFromDisk : public nsIRunnable
590 {
591 public:
592   NS_DECL_THREADSAFE_ISUPPORTS
593   NS_DECL_NSIRUNNABLE
594 
595   AsyncDeleteIconFromDisk(const nsAString &aIconPath);
596 
597 private:
598   virtual ~AsyncDeleteIconFromDisk();
599 
600   nsAutoString mIconPath;
601 };
602 
603 class AsyncDeleteAllFaviconsFromDisk : public nsIRunnable
604 {
605 public:
606   NS_DECL_THREADSAFE_ISUPPORTS
607   NS_DECL_NSIRUNNABLE
608 
609   AsyncDeleteAllFaviconsFromDisk(bool aIgnoreRecent = false);
610 
611 private:
612   virtual ~AsyncDeleteAllFaviconsFromDisk();
613 
614   int32_t mIcoNoDeleteSeconds;
615   bool mIgnoreRecent;
616 };
617 
618 class FaviconHelper
619 {
620 public:
621   static const char kJumpListCacheDir[];
622   static const char kShortcutCacheDir[];
623   static nsresult ObtainCachedIconFile(nsCOMPtr<nsIURI> aFaviconPageURI,
624                                        nsString &aICOFilePath,
625                                        nsCOMPtr<nsIThread> &aIOThread,
626                                        bool aURLShortcut);
627 
628   static nsresult HashURI(nsCOMPtr<nsICryptoHash> &aCryptoHash,
629                           nsIURI *aUri,
630                           nsACString& aUriHash);
631 
632   static nsresult GetOutputIconPath(nsCOMPtr<nsIURI> aFaviconPageURI,
633                                     nsCOMPtr<nsIFile> &aICOFile,
634                                     bool aURLShortcut);
635 
636   static nsresult
637   CacheIconFileFromFaviconURIAsync(nsCOMPtr<nsIURI> aFaviconPageURI,
638                                    nsCOMPtr<nsIFile> aICOFile,
639                                    nsCOMPtr<nsIThread> &aIOThread,
640                                    bool aURLShortcut);
641 
642   static int32_t GetICOCacheSecondsTimeout();
643 };
644 
645 } // namespace widget
646 } // namespace mozilla
647 
648 #endif // mozilla_widget_WinUtils_h__
649