Skip to content

Commit 95daf24

Browse files
committed
Bug 835698 - 'Pre-open() and send the fd for app process's application.zip'. r=jduell.
1 parent 720414a commit 95daf24

19 files changed

+936
-113
lines changed

dom/ipc/Makefile.in

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
2222
TEST_DIRS += tests
2323
endif
2424

25-
EXPORTS = PCOMContentPermissionRequestChild.h
25+
EXPORTS = \
26+
nsICachedFileDescriptorListener.h \
27+
PCOMContentPermissionRequestChild.h \
28+
$(NULL)
2629

2730
EXPORTS_NAMESPACES = \
2831
mozilla \

dom/ipc/PBrowser.ipdl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ using gfxSize;
3131
using mozilla::layers::LayersBackend;
3232
using mozilla::layers::FrameMetrics;
3333
using mozilla::layout::ScrollingBehavior;
34+
using mozilla::void_t;
3435
using mozilla::WindowsHandle;
3536
using nscolor;
3637
using nsCompositionEvent;
@@ -290,6 +291,8 @@ child:
290291

291292
LoadURL(nsCString uri);
292293

294+
CacheFileDescriptor(nsString path, FileDescriptor fd);
295+
293296
UpdateDimensions(nsRect rect, nsIntSize size, ScreenOrientation orientation) compress;
294297

295298
UpdateFrame(FrameMetrics frame) compress;

dom/ipc/TabChild.cpp

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "mozilla/dom/PContentChild.h"
1919
#include "mozilla/dom/PContentDialogChild.h"
2020
#include "mozilla/ipc/DocumentRendererChild.h"
21+
#include "mozilla/ipc/FileDescriptorUtils.h"
2122
#include "mozilla/layers/AsyncPanZoomController.h"
2223
#include "mozilla/layers/CompositorChild.h"
2324
#include "mozilla/layers/PLayersChild.h"
@@ -37,6 +38,7 @@
3738
#include "mozilla/dom/Element.h"
3839
#include "nsIAppsService.h"
3940
#include "nsIBaseWindow.h"
41+
#include "nsICachedFileDescriptorListener.h"
4042
#include "nsIComponentManager.h"
4143
#include "nsIDocumentInlines.h"
4244
#include "nsIDOMClassInfo.h"
@@ -121,6 +123,98 @@ class ContentDialogChild : public PContentDialogChild
121123
const InfallibleTArray<nsString>& aStringParams);
122124
};
123125

126+
class TabChild::CachedFileDescriptorInfo
127+
{
128+
struct PathOnlyComparatorHelper
129+
{
130+
bool Equals(const nsAutoPtr<CachedFileDescriptorInfo>& a,
131+
const CachedFileDescriptorInfo& b) const
132+
{
133+
return a->mPath == b.mPath;
134+
}
135+
};
136+
137+
struct PathAndCallbackComparatorHelper
138+
{
139+
bool Equals(const nsAutoPtr<CachedFileDescriptorInfo>& a,
140+
const CachedFileDescriptorInfo& b) const
141+
{
142+
return a->mPath == b.mPath &&
143+
a->mCallback == b.mCallback;
144+
}
145+
};
146+
147+
public:
148+
nsString mPath;
149+
FileDescriptor mFileDescriptor;
150+
nsCOMPtr<nsICachedFileDescriptorListener> mCallback;
151+
bool mCanceled;
152+
153+
CachedFileDescriptorInfo(const nsAString& aPath)
154+
: mPath(aPath), mCanceled(false)
155+
{ }
156+
157+
CachedFileDescriptorInfo(const nsAString& aPath,
158+
const FileDescriptor& aFileDescriptor)
159+
: mPath(aPath), mFileDescriptor(aFileDescriptor), mCanceled(false)
160+
{ }
161+
162+
CachedFileDescriptorInfo(const nsAString& aPath,
163+
nsICachedFileDescriptorListener* aCallback)
164+
: mPath(aPath), mCallback(aCallback), mCanceled(false)
165+
{ }
166+
167+
PathOnlyComparatorHelper PathOnlyComparator() const
168+
{
169+
return PathOnlyComparatorHelper();
170+
}
171+
172+
PathAndCallbackComparatorHelper PathAndCallbackComparator() const
173+
{
174+
return PathAndCallbackComparatorHelper();
175+
}
176+
177+
void FireCallback() const
178+
{
179+
mCallback->OnCachedFileDescriptor(mPath, mFileDescriptor);
180+
}
181+
};
182+
183+
class TabChild::CachedFileDescriptorCallbackRunnable : public nsRunnable
184+
{
185+
typedef TabChild::CachedFileDescriptorInfo CachedFileDescriptorInfo;
186+
187+
nsAutoPtr<CachedFileDescriptorInfo> mInfo;
188+
189+
public:
190+
CachedFileDescriptorCallbackRunnable(CachedFileDescriptorInfo* aInfo)
191+
: mInfo(aInfo)
192+
{
193+
MOZ_ASSERT(NS_IsMainThread());
194+
MOZ_ASSERT(aInfo);
195+
MOZ_ASSERT(!aInfo->mPath.IsEmpty());
196+
MOZ_ASSERT(aInfo->mCallback);
197+
}
198+
199+
void Dispatch()
200+
{
201+
MOZ_ASSERT(NS_IsMainThread());
202+
203+
nsresult rv = NS_DispatchToCurrentThread(this);
204+
NS_ENSURE_SUCCESS_VOID(rv);
205+
}
206+
207+
private:
208+
NS_IMETHOD Run()
209+
{
210+
MOZ_ASSERT(NS_IsMainThread());
211+
MOZ_ASSERT(mInfo);
212+
213+
mInfo->FireCallback();
214+
return NS_OK;
215+
}
216+
};
217+
124218
StaticRefPtr<TabChild> sPreallocatedTab;
125219

126220
/*static*/ void
@@ -1119,6 +1213,130 @@ TabChild::RecvLoadURL(const nsCString& uri)
11191213
return true;
11201214
}
11211215

1216+
bool
1217+
TabChild::RecvCacheFileDescriptor(const nsString& aPath,
1218+
const FileDescriptor& aFileDescriptor)
1219+
{
1220+
MOZ_ASSERT(NS_IsMainThread());
1221+
MOZ_ASSERT(!aPath.IsEmpty());
1222+
1223+
// aFileDescriptor may be invalid here, but the callback will choose how to
1224+
// handle it.
1225+
1226+
// First see if we already have a request for this path.
1227+
const CachedFileDescriptorInfo search(aPath);
1228+
uint32_t index =
1229+
mCachedFileDescriptorInfos.IndexOf(search, 0,
1230+
search.PathOnlyComparator());
1231+
if (index == mCachedFileDescriptorInfos.NoIndex) {
1232+
// We haven't had any requests for this path yet. Assume that we will
1233+
// in a little while and save the file descriptor here.
1234+
mCachedFileDescriptorInfos.AppendElement(
1235+
new CachedFileDescriptorInfo(aPath, aFileDescriptor));
1236+
return true;
1237+
}
1238+
1239+
nsAutoPtr<CachedFileDescriptorInfo>& info =
1240+
mCachedFileDescriptorInfos[index];
1241+
1242+
MOZ_ASSERT(info);
1243+
MOZ_ASSERT(info->mPath == aPath);
1244+
MOZ_ASSERT(!info->mFileDescriptor.IsValid());
1245+
MOZ_ASSERT(info->mCallback);
1246+
1247+
// If this callback has been canceled then we can simply close the file
1248+
// descriptor and forget about the callback.
1249+
if (info->mCanceled) {
1250+
// Only close if this is a valid file descriptor.
1251+
if (aFileDescriptor.IsValid()) {
1252+
nsRefPtr<CloseFileRunnable> runnable =
1253+
new CloseFileRunnable(aFileDescriptor);
1254+
runnable->Dispatch();
1255+
}
1256+
} else {
1257+
// Not canceled so fire the callback.
1258+
info->mFileDescriptor = aFileDescriptor;
1259+
1260+
// We don't need a runnable here because we should already be at the top
1261+
// of the event loop. Just fire immediately.
1262+
info->FireCallback();
1263+
}
1264+
1265+
mCachedFileDescriptorInfos.RemoveElementAt(index);
1266+
return true;
1267+
}
1268+
1269+
bool
1270+
TabChild::GetCachedFileDescriptor(const nsAString& aPath,
1271+
nsICachedFileDescriptorListener* aCallback)
1272+
{
1273+
MOZ_ASSERT(NS_IsMainThread());
1274+
MOZ_ASSERT(!aPath.IsEmpty());
1275+
MOZ_ASSERT(aCallback);
1276+
1277+
// First see if we've already received a cached file descriptor for this
1278+
// path.
1279+
const CachedFileDescriptorInfo search(aPath);
1280+
uint32_t index =
1281+
mCachedFileDescriptorInfos.IndexOf(search, 0,
1282+
search.PathOnlyComparator());
1283+
if (index == mCachedFileDescriptorInfos.NoIndex) {
1284+
// We haven't received a file descriptor for this path yet. Assume that
1285+
// we will in a little while and save the request here.
1286+
mCachedFileDescriptorInfos.AppendElement(
1287+
new CachedFileDescriptorInfo(aPath, aCallback));
1288+
return false;
1289+
}
1290+
1291+
nsAutoPtr<CachedFileDescriptorInfo>& info =
1292+
mCachedFileDescriptorInfos[index];
1293+
1294+
MOZ_ASSERT(info);
1295+
MOZ_ASSERT(info->mPath == aPath);
1296+
MOZ_ASSERT(!info->mCallback);
1297+
MOZ_ASSERT(!info->mCanceled);
1298+
1299+
info->mCallback = aCallback;
1300+
1301+
nsRefPtr<CachedFileDescriptorCallbackRunnable> runnable =
1302+
new CachedFileDescriptorCallbackRunnable(info);
1303+
runnable->Dispatch();
1304+
1305+
mCachedFileDescriptorInfos.RemoveElementAt(index);
1306+
return true;
1307+
}
1308+
1309+
void
1310+
TabChild::CancelCachedFileDescriptorCallback(
1311+
const nsAString& aPath,
1312+
nsICachedFileDescriptorListener* aCallback)
1313+
{
1314+
MOZ_ASSERT(NS_IsMainThread());
1315+
MOZ_ASSERT(!aPath.IsEmpty());
1316+
MOZ_ASSERT(aCallback);
1317+
1318+
const CachedFileDescriptorInfo search(aPath, aCallback);
1319+
uint32_t index =
1320+
mCachedFileDescriptorInfos.IndexOf(search, 0,
1321+
search.PathAndCallbackComparator());
1322+
if (index == mCachedFileDescriptorInfos.NoIndex) {
1323+
// Nothing to do here.
1324+
return;
1325+
}
1326+
1327+
nsAutoPtr<CachedFileDescriptorInfo>& info =
1328+
mCachedFileDescriptorInfos[index];
1329+
1330+
MOZ_ASSERT(info);
1331+
MOZ_ASSERT(info->mPath == aPath);
1332+
MOZ_ASSERT(!info->mFileDescriptor.IsValid());
1333+
MOZ_ASSERT(info->mCallback == aCallback);
1334+
MOZ_ASSERT(!info->mCanceled);
1335+
1336+
// Set this flag so that we will close the file descriptor when it arrives.
1337+
info->mCanceled = true;
1338+
}
1339+
11221340
void
11231341
TabChild::DoFakeShow()
11241342
{

dom/ipc/TabChild.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "mozilla/dom/TabContext.h"
5555

5656
struct gfxMatrix;
57+
class nsICachedFileDescriptorListener;
5758

5859
namespace mozilla {
5960
namespace layout {
@@ -196,6 +197,9 @@ class TabChild : public PBrowserChild,
196197
const mozilla::dom::StructuredCloneData& aData);
197198

198199
virtual bool RecvLoadURL(const nsCString& uri);
200+
virtual bool RecvCacheFileDescriptor(const nsString& aPath,
201+
const FileDescriptor& aFileDescriptor)
202+
MOZ_OVERRIDE;
199203
virtual bool RecvShow(const nsIntSize& size);
200204
virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size, const ScreenOrientation& orientation);
201205
virtual bool RecvUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
@@ -317,6 +321,15 @@ class TabChild : public PBrowserChild,
317321
*/
318322
void GetAppType(nsAString& aAppType) const { aAppType = mAppType; }
319323

324+
// Returns true if the file descriptor was found in the cache, false
325+
// otherwise.
326+
bool GetCachedFileDescriptor(const nsAString& aPath,
327+
nsICachedFileDescriptorListener* aCallback);
328+
329+
void CancelCachedFileDescriptorCallback(
330+
const nsAString& aPath,
331+
nsICachedFileDescriptorListener* aCallback);
332+
320333
protected:
321334
virtual PRenderFrameChild* AllocPRenderFrame(ScrollingBehavior* aScrolling,
322335
LayersBackend* aBackend,
@@ -412,6 +425,9 @@ class TabChild : public PBrowserChild,
412425
return utils;
413426
}
414427

428+
class CachedFileDescriptorInfo;
429+
class CachedFileDescriptorCallbackRunnable;
430+
415431
nsCOMPtr<nsIWebNavigation> mWebNav;
416432
nsCOMPtr<nsIWidget> mWidget;
417433
nsCOMPtr<nsIURI> mLastURI;
@@ -430,6 +446,9 @@ class TabChild : public PBrowserChild,
430446
// the touch we're tracking. That is, if touchend or a touchmove
431447
// that exceeds the gesture threshold doesn't happen.
432448
CancelableTask* mTapHoldTimer;
449+
// At present only 1 of these is really expected.
450+
nsAutoTArray<nsAutoPtr<CachedFileDescriptorInfo>, 1>
451+
mCachedFileDescriptorInfos;
433452
float mOldViewportWidth;
434453
nscolor mLastBackgroundColor;
435454
ScrollingBehavior mScrolling;

0 commit comments

Comments
 (0)