зеркало из https://github.com/mozilla/gecko-dev.git
Bug 785662 - Add NS_OpenAnonymousTemporaryFile(), and use it in nsMediaCache::Init(). r=roc
--HG-- rename : xpcom/io/nsMediaCacheRemover.cpp => xpcom/io/nsAnonymousTemporaryFile.cpp
This commit is contained in:
Родитель
9e4d2691db
Коммит
d7f1641d0d
|
@ -8,9 +8,6 @@
|
|||
#include "mozilla/XPCOM.h"
|
||||
|
||||
#include "nsMediaCache.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "prio.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -21,6 +18,7 @@
|
|||
#include "mozilla/Preferences.h"
|
||||
#include "FileBlockCache.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsAnonymousTemporaryFile.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -519,47 +517,8 @@ nsMediaCache::Init()
|
|||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||
NS_ASSERTION(!mFileCache, "Cache file already open?");
|
||||
|
||||
// In single process Gecko, store the media cache in the profile directory
|
||||
// so that multiple users can use separate media caches concurrently.
|
||||
// In multi-process Gecko, there is no profile dir, so just store it in the
|
||||
// system temp directory instead.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> tmpFile;
|
||||
const char* dir = (XRE_GetProcessType() == GeckoProcessType_Content) ?
|
||||
NS_OS_TEMP_DIR : NS_APP_USER_PROFILE_LOCAL_50_DIR;
|
||||
rv = NS_GetSpecialDirectory(dir, getter_AddRefs(tmpFile));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
// We put the media cache file in
|
||||
// ${TempDir}/mozilla-media-cache/media_cache
|
||||
rv = tmpFile->AppendNative(nsDependentCString("mozilla-media-cache"));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = tmpFile->Create(nsIFile::DIRECTORY_TYPE, 0700);
|
||||
if (rv == NS_ERROR_FILE_ALREADY_EXISTS) {
|
||||
// Ensure the permissions are 0700. If not, we won't be able to create,
|
||||
// read to and write from the media cache file in its subdirectory on
|
||||
// non-Windows platforms.
|
||||
uint32_t perms;
|
||||
rv = tmpFile->GetPermissions(&perms);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
if (perms != 0700) {
|
||||
rv = tmpFile->SetPermissions(0700);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
} else {
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
rv = tmpFile->AppendNative(nsDependentCString("media_cache"));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = tmpFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0700);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
PRFileDesc* fileDesc = nullptr;
|
||||
rv = tmpFile->OpenNSPRFileDesc(PR_RDWR | nsIFile::DELETE_ON_CLOSE,
|
||||
PR_IRWXU, &fileDesc);
|
||||
nsresult rv = NS_OpenAnonymousTemporaryFile(&fileDesc);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
mFileCache = new FileBlockCache();
|
||||
|
|
|
@ -141,7 +141,7 @@ extern nsresult NS_RegistryGetFactory(nsIFactory** aFactory);
|
|||
extern nsresult NS_CategoryManagerGetFactory( nsIFactory** );
|
||||
|
||||
#ifdef XP_WIN
|
||||
extern nsresult ScheduleMediaCacheRemover();
|
||||
extern nsresult CreateAnonTempFileRemover();
|
||||
#endif
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsProcess)
|
||||
|
@ -464,7 +464,7 @@ NS_InitXPCOM2(nsIServiceManager* *result,
|
|||
nullptr,
|
||||
NS_XPCOM_STARTUP_OBSERVER_ID);
|
||||
#ifdef XP_WIN
|
||||
ScheduleMediaCacheRemover();
|
||||
CreateAnonTempFileRemover();
|
||||
#endif
|
||||
|
||||
mozilla::MapsMemoryReporter::Init();
|
||||
|
|
|
@ -26,6 +26,7 @@ endif
|
|||
|
||||
CPPSRCS = \
|
||||
Base64.cpp \
|
||||
nsAnonymousTemporaryFile.cpp \
|
||||
nsAppFileLocationProvider.cpp \
|
||||
nsBinaryStream.cpp \
|
||||
nsDirectoryService.cpp \
|
||||
|
@ -58,13 +59,14 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
|
|||
CPPSRCS += nsLocalFileOS2.cpp
|
||||
else
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
CPPSRCS += nsLocalFileWin.cpp nsMediaCacheRemover.cpp
|
||||
CPPSRCS += nsLocalFileWin.cpp
|
||||
else
|
||||
CPPSRCS += nsLocalFileUnix.cpp
|
||||
endif # windows
|
||||
endif # OS2
|
||||
|
||||
EXPORTS = \
|
||||
nsAnonymousTemporaryFile.h \
|
||||
nsAppDirectoryServiceDefs.h \
|
||||
nsDirectoryService.h \
|
||||
nsDirectoryServiceAtomList.h \
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
|
||||
#include "nsAnonymousTemporaryFile.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsIIdleService.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
using namespace mozilla;
|
||||
#endif
|
||||
|
||||
|
||||
// We store the temp files in the system temp dir.
|
||||
//
|
||||
// On Windows systems in particular we use a sub-directory of the temp
|
||||
// directory, because:
|
||||
// 1. DELETE_ON_CLOSE is unreliable on Windows, in particular if we power
|
||||
// cycle (and perhaps if we crash) the files are not deleted. We store
|
||||
// the temporary files in a known sub-dir so that we can find and delete
|
||||
// them easily and quickly.
|
||||
// 2. On Windows NT the system temp dir is in the user's $HomeDir/AppData,
|
||||
// so we can be sure the user always has write privileges to that directory;
|
||||
// if the sub-dir for our temp files was in some shared location and
|
||||
// was created by a privileged user, it's possible that other users
|
||||
// wouldn't have write access to that sub-dir. (Non-Windows systems
|
||||
// don't store their temp files in a sub-dir, so this isn't an issue on
|
||||
// those platforms).
|
||||
// 3. Content processes can access the system temp dir
|
||||
// (NS_GetSpecialDirectory fails on NS_APP_USER_PROFILE_LOCAL_50_DIR
|
||||
// for content process for example, which is where we previously stored
|
||||
// temp files on Windows). This argument applies to all platforms, not
|
||||
// just Windows.
|
||||
static nsresult
|
||||
GetTempDir(nsIFile** aTempDir)
|
||||
{
|
||||
NS_ENSURE_ARG(aTempDir);
|
||||
nsCOMPtr<nsIFile> tmpFile;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpFile));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
#ifdef XP_WIN
|
||||
// On windows DELETE_ON_CLOSE is unreliable, so we store temporary files
|
||||
// in a subdir of the temp dir and delete that in an idle service observer
|
||||
// to ensure it's been cleared.
|
||||
rv = tmpFile->AppendNative(nsDependentCString("mozilla-temp-files"));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = tmpFile->Create(nsIFile::DIRECTORY_TYPE, 0700);
|
||||
NS_ENSURE_TRUE(rv == NS_ERROR_FILE_ALREADY_EXISTS || NS_SUCCEEDED(rv), rv);
|
||||
#endif
|
||||
|
||||
tmpFile.forget(aTempDir);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_OpenAnonymousTemporaryFile(PRFileDesc** aOutFileDesc)
|
||||
{
|
||||
NS_ENSURE_ARG(aOutFileDesc);
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIFile> tmpFile;
|
||||
rv = GetTempDir(getter_AddRefs(tmpFile));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
// Give the temp file a name with a random element. CreateUnique will also
|
||||
// append a counter to the name if it encounters a name collision. Adding
|
||||
// a random element to the name reduces the likelihood of a name collision,
|
||||
// so that CreateUnique() doesn't end up trying a lot of name variants in
|
||||
// its "try appending an incrementing counter" loop, as file IO can be
|
||||
// expensive on some mobile flash drives.
|
||||
nsAutoCString name("mozilla-temp-");
|
||||
name.AppendInt(rand());
|
||||
|
||||
rv = tmpFile->AppendNative(name);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = tmpFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0700);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = tmpFile->OpenNSPRFileDesc(PR_RDWR | nsIFile::DELETE_ON_CLOSE,
|
||||
PR_IRWXU, aOutFileDesc);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
||||
// On Windows we have an idle service observer that runs some time after
|
||||
// startup and deletes any stray anonymous temporary files...
|
||||
|
||||
// Duration of idle time before we'll get a callback whereupon we attempt to
|
||||
// remove any stray and unused anonymous temp files.
|
||||
#define TEMP_FILE_IDLE_TIME_S 30
|
||||
|
||||
// The nsAnonTempFileRemover is created in a timer, which sets an idle observer.
|
||||
// This is expiration time (in ms) which initial timer is set for (3 minutes).
|
||||
#define SCHEDULE_TIMEOUT_MS 3 * 60 * 1000
|
||||
|
||||
#define XPCOM_SHUTDOWN_TOPIC "xpcom-shutdown"
|
||||
|
||||
// This class adds itself as an idle observer. When the application has
|
||||
// been idle for about 30 seconds we'll get a notification, whereupon we'll
|
||||
// attempt to delete ${TempDir}/mozilla-temp-files/. This is to ensure all
|
||||
// temp files that were supposed to be deleted on application exit were actually
|
||||
// deleted, as they may not be if we previously crashed. See bugs 572579 and
|
||||
// 785662. This is only needed on some versions of Windows,
|
||||
// nsIFile::DELETE_ON_CLOSE works on other platforms.
|
||||
// This class adds itself as a shutdown observer so that it can cancel the
|
||||
// idle observer and its timer on shutdown. Note: the observer and idle
|
||||
// services hold references to instances of this object, and those references
|
||||
// are what keep this object alive.
|
||||
class nsAnonTempFileRemover : public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsAnonTempFileRemover() {
|
||||
MOZ_COUNT_CTOR(nsAnonTempFileRemover);
|
||||
}
|
||||
|
||||
~nsAnonTempFileRemover() {
|
||||
MOZ_COUNT_DTOR(nsAnonTempFileRemover);
|
||||
}
|
||||
|
||||
nsresult Init() {
|
||||
// We add the idle observer in a timer, so that the app has enough
|
||||
// time to start up before we add the idle observer. If we register the
|
||||
// idle observer too early, it will be registered before the fake idle
|
||||
// service is installed when running in xpcshell, and this interferes with
|
||||
// the fake idle service, causing xpcshell-test failures.
|
||||
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(mTimer != nullptr, NS_ERROR_FAILURE);
|
||||
nsresult rv = mTimer->Init(this,
|
||||
SCHEDULE_TIMEOUT_MS,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Register shutdown observer so we can cancel the timer if we shutdown before
|
||||
// the timer runs.
|
||||
nsCOMPtr<nsIObserverService> obsSrv = services::GetObserverService();
|
||||
NS_ENSURE_TRUE(obsSrv != nullptr, NS_ERROR_FAILURE);
|
||||
return obsSrv->AddObserver(this, XPCOM_SHUTDOWN_TOPIC, false);
|
||||
}
|
||||
|
||||
void Cleanup() {
|
||||
// Cancel timer.
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
mTimer = nullptr;
|
||||
}
|
||||
// Remove idle service observer.
|
||||
nsCOMPtr<nsIIdleService> idleSvc =
|
||||
do_GetService("@mozilla.org/widget/idleservice;1");
|
||||
if (idleSvc) {
|
||||
idleSvc->RemoveIdleObserver(this, TEMP_FILE_IDLE_TIME_S);
|
||||
}
|
||||
// Remove shutdown observer.
|
||||
nsCOMPtr<nsIObserverService> obsSrv = services::GetObserverService();
|
||||
if (obsSrv) {
|
||||
obsSrv->RemoveObserver(this, XPCOM_SHUTDOWN_TOPIC);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
if (nsCRT::strcmp(aTopic, NS_TIMER_CALLBACK_TOPIC) == 0 &&
|
||||
NS_FAILED(RegisterIdleObserver())) {
|
||||
Cleanup();
|
||||
} else if (nsCRT::strcmp(aTopic, OBSERVER_TOPIC_IDLE) == 0) {
|
||||
// The user has been idle for a while, clean up the temp files.
|
||||
// The idle service will drop its reference to this object after
|
||||
// we exit, destroying this object.
|
||||
RemoveAnonTempFileFiles();
|
||||
Cleanup();
|
||||
} else if (nsCRT::strcmp(aTopic, XPCOM_SHUTDOWN_TOPIC) == 0) {
|
||||
Cleanup();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult RegisterIdleObserver() {
|
||||
// Add this as an idle observer. When we've been idle for
|
||||
// TEMP_FILE_IDLE_TIME_S seconds, we'll get a notification, and we'll then
|
||||
// try to delete any stray temp files.
|
||||
nsCOMPtr<nsIIdleService> idleSvc =
|
||||
do_GetService("@mozilla.org/widget/idleservice;1");
|
||||
if (!idleSvc)
|
||||
return NS_ERROR_FAILURE;
|
||||
return idleSvc->AddIdleObserver(this, TEMP_FILE_IDLE_TIME_S);
|
||||
}
|
||||
|
||||
void RemoveAnonTempFileFiles() {
|
||||
nsCOMPtr<nsIFile> tmpDir;
|
||||
nsresult rv = GetTempDir(getter_AddRefs(tmpDir));
|
||||
NS_ENSURE_SUCCESS(rv,);
|
||||
|
||||
// Remove the directory recursively.
|
||||
tmpDir->Remove(true);
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsAnonTempFileRemover, nsIObserver)
|
||||
|
||||
nsresult CreateAnonTempFileRemover() {
|
||||
// Create a temp file remover. If Init() succeeds, the temp file remover is kept
|
||||
// alive by a reference held by the observer service, since the temp file remover
|
||||
// is a shutdown observer. We only create the temp file remover if we're running
|
||||
// in the main process; there's no point in doing the temp file removal multiple
|
||||
// times per startup.
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsRefPtr<nsAnonTempFileRemover> tempRemover = new nsAnonTempFileRemover();
|
||||
return tempRemover->Init();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "prio.h"
|
||||
#include "nscore.h"
|
||||
|
||||
/**
|
||||
* OpenAnonymousTemporaryFile
|
||||
*
|
||||
* Creates and opens a temporary file which has a random name. Callers have no
|
||||
* control over the file name, and the file is opened in a temporary location
|
||||
* which is appropriate for the platform.
|
||||
*
|
||||
* Upon success, aOutFileDesc contains an opened handle to the temporary file.
|
||||
* The caller is responsible for closing the file when they're finished with it.
|
||||
*
|
||||
* The file will be deleted when the file handle is closed. On non-Windows
|
||||
* platforms the file will be unlinked before this function returns. On Windows
|
||||
* the OS supplied delete-on-close mechanism is unreliable if the application
|
||||
* crashes or the computer power cycles unexpectedly, so unopened temporary
|
||||
* files are purged at some time after application startup.
|
||||
*
|
||||
*/
|
||||
nsresult
|
||||
NS_OpenAnonymousTemporaryFile(PRFileDesc** aOutFileDesc);
|
||||
|
|
@ -344,7 +344,17 @@ interface nsIFile : nsISupports
|
|||
*/
|
||||
attribute boolean followLinks;
|
||||
|
||||
/**
|
||||
* Flag for openNSPRFileDesc(), to hint to the OS that the file will be
|
||||
* read sequentially with agressive readahead.
|
||||
*/
|
||||
const unsigned long OS_READAHEAD = 0x40000000;
|
||||
|
||||
/**
|
||||
* Flag for openNSPRFileDesc(). Deprecated and unreliable!
|
||||
* Instead use NS_OpenAnonymousTemporaryFile() to create a temporary
|
||||
* file which will be deleted upon close!
|
||||
*/
|
||||
const unsigned long DELETE_ON_CLOSE = 0x80000000;
|
||||
|
||||
/**
|
||||
|
@ -354,10 +364,9 @@ interface nsIFile : nsISupports
|
|||
* @param flags the PR_Open flags from prio.h, plus optionally
|
||||
* OS_READAHEAD or DELETE_ON_CLOSE. OS_READAHEAD is a hint to the
|
||||
* OS that the file will be read sequentially with agressive
|
||||
* readahead. DELETE_ON_CLOSE may be implemented by removing the
|
||||
* file (by path name) immediately after opening it, so beware of
|
||||
* possible races; the file should be exclusively owned by this
|
||||
* process.
|
||||
* readahead. DELETE_ON_CLOSE is unreliable on Windows and is deprecated.
|
||||
* Instead use NS_OpenAnonymousTemporaryFile() to create a temporary
|
||||
* file which will be deleted upon close.
|
||||
*/
|
||||
[noscript] PRFileDescStar openNSPRFileDesc(in long flags, in long mode);
|
||||
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
/* 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 XP_WIN
|
||||
#error nsMediaCacheRemover only needed on Windows.
|
||||
#endif
|
||||
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIIdleService.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsString.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
// Duration of idle time before we'll get a callback whereupon we attempt to
|
||||
// remove any stray and unused media cache temp files.
|
||||
#define TEMP_FILE_IDLE_TIME 30
|
||||
|
||||
// The nsMediaCacheRemover is created in a timer, which sets an idle observer.
|
||||
// This is expiration time (in ms) which initial timer is set for (3 minutes).
|
||||
#define SCHEDULE_TIMEOUT 3 * 60 * 1000
|
||||
|
||||
// This class adds itself as an idle observer. When the application has
|
||||
// been idle for about 30 seconds we'll get a notification, whereupon we'll
|
||||
// attempt to delete ${TempDir}/mozilla-media-cache/. This is to ensure all
|
||||
// media cache temp files which were supposed to be deleted on application
|
||||
// exit were actually deleted as they may not be if we previously crashed.
|
||||
// See bug 572579. This is only needed on some versions of Windows,
|
||||
// nsIFile::DELETE_ON_CLOSE works on other platforms.
|
||||
class nsMediaCacheRemover : public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsMediaCacheRemover() {
|
||||
MOZ_COUNT_CTOR(nsMediaCacheRemover);
|
||||
}
|
||||
|
||||
~nsMediaCacheRemover() {
|
||||
MOZ_COUNT_DTOR(nsMediaCacheRemover);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Observe(nsISupports *subject,
|
||||
const char *topic,
|
||||
const PRUnichar *data)
|
||||
{
|
||||
if (strcmp(topic, "idle") == 0) {
|
||||
// The user has been idle for a while, clean up the temp files.
|
||||
// The idle service will drop its reference to this object after
|
||||
// we exit, destroying this object.
|
||||
RemoveMediaCacheFiles();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult RegisterIdleObserver() {
|
||||
// Add this as an idle observer. When we've been idle for
|
||||
// TEMP_FILE_IDLE_TIME seconds, we'll get a notification, and we'll then
|
||||
// try to delete any stray media cache temp files.
|
||||
nsCOMPtr<nsIIdleService> idleSvc =
|
||||
do_GetService("@mozilla.org/widget/idleservice;1");
|
||||
if (!idleSvc)
|
||||
return NS_ERROR_FAILURE;
|
||||
return idleSvc->AddIdleObserver(this, TEMP_FILE_IDLE_TIME);
|
||||
}
|
||||
|
||||
void RemoveMediaCacheFiles() {
|
||||
nsCOMPtr<nsIIdleService> idleSvc =
|
||||
do_GetService("@mozilla.org/widget/idleservice;1");
|
||||
if (idleSvc)
|
||||
idleSvc->RemoveIdleObserver(this, TEMP_FILE_IDLE_TIME);
|
||||
|
||||
nsCOMPtr<nsIFile> tmpDir;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_LOCAL_50_DIR,
|
||||
getter_AddRefs(tmpDir));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
NS_ABORT_IF_FALSE(XRE_GetProcessType() == GeckoProcessType_Default,
|
||||
"Need to update media cache file location");
|
||||
|
||||
rv = tmpDir->AppendNative(nsDependentCString("mozilla-media-cache"));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
// Remove the directory recursively.
|
||||
tmpDir->Remove(true);
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsMediaCacheRemover, nsIObserver)
|
||||
|
||||
void CreateMediaCacheRemover(nsITimer* aTimer, void* aClosure) {
|
||||
// Create a new nsMediaCacheRemover, and register it as an idle observer.
|
||||
// If it is successfully registered as an idle observer, its owning reference
|
||||
// will be held by the idle service, otherwise it will be destroyed by the
|
||||
// refptr here when it goes out of scope.
|
||||
nsRefPtr<nsMediaCacheRemover> t = new nsMediaCacheRemover();
|
||||
t->RegisterIdleObserver();
|
||||
}
|
||||
|
||||
nsresult ScheduleMediaCacheRemover() {
|
||||
// We create the nsMediaCacheRemover in a timer, so that the app has enough
|
||||
// time to start up before we add the idle observer. If we register the
|
||||
// idle observer too early, it will be registered before the fake idle
|
||||
// service is installed when running in xpcshell, and this interferes with
|
||||
// the fake idle service, causing xpcshell-test failures.
|
||||
nsCOMPtr<nsITimer> t = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
nsresult res = t->InitWithFuncCallback(CreateMediaCacheRemover,
|
||||
0,
|
||||
SCHEDULE_TIMEOUT,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
return res;
|
||||
}
|
Загрузка…
Ссылка в новой задаче