Bug 874689 - Move android file picker to a js component. r=mfinkle

This commit is contained in:
Wes Johnston 2013-05-29 08:08:55 -07:00
Родитель 9c540a5368
Коммит 0f805b15bc
14 изменённых файлов: 418 добавлений и 234 удалений

Просмотреть файл

@ -7,6 +7,7 @@ package org.mozilla.gecko;
import org.mozilla.gecko.util.ActivityResultHandler;
import org.mozilla.gecko.util.ActivityResultHandlerMap;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.util.GeckoEventListener;
import org.json.JSONException;
import org.json.JSONObject;
@ -28,7 +29,7 @@ import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
public class ActivityHandlerHelper {
public class ActivityHandlerHelper implements GeckoEventListener {
private static final String LOGTAG = "GeckoActivityHandlerHelper";
private final ConcurrentLinkedQueue<String> mFilePickerResult;
@ -39,6 +40,10 @@ public class ActivityHandlerHelper {
private final CameraImageResultHandler mCameraImageResultHandler;
private final CameraVideoResultHandler mCameraVideoResultHandler;
public interface FileResultHandler {
public void gotFile(String filename);
}
@SuppressWarnings("serial")
public ActivityHandlerHelper() {
mFilePickerResult = new ConcurrentLinkedQueue<String>() {
@ -56,6 +61,34 @@ public class ActivityHandlerHelper {
mAwesomebarResultHandler = new AwesomebarResultHandler();
mCameraImageResultHandler = new CameraImageResultHandler(mFilePickerResult);
mCameraVideoResultHandler = new CameraVideoResultHandler(mFilePickerResult);
GeckoAppShell.getEventDispatcher().registerEventListener("FilePicker:Show", this);
}
@Override
public void handleMessage(String event, final JSONObject message) {
if (event.equals("FilePicker:Show")) {
String mimeType = "*/*";
String mode = message.optString("mode");
if ("mimeType".equals(mode))
mimeType = message.optString("mimeType");
else if ("extension".equals(mode))
mimeType = GeckoAppShell.getMimeTypeFromExtensions(message.optString("extensions"));
Log.i(LOGTAG, "Mime: " + mimeType);
showFilePickerAsync(GeckoAppShell.getGeckoInterface().getActivity(), mimeType, new FileResultHandler() {
public void gotFile(String filename) {
try {
message.put("file", filename);
} catch (JSONException ex) {
Log.i(LOGTAG, "Can't add filename to message " + filename);
}
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(
"FilePicker:Result", message.toString()));
}
});
}
}
public int makeRequestCodeForAwesomebar() {
@ -149,6 +182,57 @@ public class ActivityHandlerHelper {
}
}
private interface IntentHandler {
public void gotIntent(Intent intent);
}
private void getFilePickerIntentAsync(final Context context, String aMimeType, final IntentHandler handler) {
final ArrayList<Intent> intents = new ArrayList<Intent>();
final Prompt.PromptListItem[] items =
getItemsAndIntentsForFilePicker(context, aMimeType, intents);
if (intents.size() == 0) {
Log.i(LOGTAG, "no activities for the file picker!");
handler.gotIntent(null);
return;
}
if (intents.size() == 1) {
handler.gotIntent(intents.get(0));
return;
}
final Prompt prompt = new Prompt(context, new Prompt.PromptCallback() {
public void onPromptFinished(String promptServiceResult) {
int itemId = -1;
try {
itemId = new JSONObject(promptServiceResult).getInt("button");
if (itemId == -1) {
handler.gotIntent(null);
return;
}
} catch (JSONException e) {
Log.e(LOGTAG, "result from promptservice was invalid: ", e);
handler.gotIntent(null);
return;
}
if (handler != null)
handler.gotIntent(intents.get(itemId));
}
});
final String title = getFilePickerTitle(context, aMimeType);
// Runnable has to be called to show an intent-like
// context menu UI using the PromptService.
ThreadUtils.postToUiThread(new Runnable() {
@Override public void run() {
prompt.show(title, "", items, false);
}
});
}
private Intent getFilePickerIntent(Context context, String aMimeType) {
ArrayList<Intent> intents = new ArrayList<Intent>();
final Prompt.PromptListItem[] items =
@ -225,6 +309,31 @@ public class ActivityHandlerHelper {
return filePickerResult;
}
public void showFilePickerAsync(final Activity parentActivity, String aMimeType, final FileResultHandler handler) {
getFilePickerIntentAsync(parentActivity, aMimeType, new IntentHandler() {
public void gotIntent(Intent intent) {
if (intent == null) {
handler.gotFile("");
}
if (intent.getAction().equals(MediaStore.ACTION_IMAGE_CAPTURE)) {
CameraImageResultHandler cam = new CameraImageResultHandler(handler);
parentActivity.startActivityForResult(intent, mActivityResultHandlerMap.put(cam));
} else if (intent.getAction().equals(MediaStore.ACTION_VIDEO_CAPTURE)) {
CameraVideoResultHandler vid = new CameraVideoResultHandler(handler);
parentActivity.startActivityForResult(intent, mActivityResultHandlerMap.put(vid));
} else if (intent.getAction().equals(Intent.ACTION_GET_CONTENT)) {
FilePickerResultHandlerSync file = new FilePickerResultHandlerSync(handler);
parentActivity.startActivityForResult(intent, mActivityResultHandlerMap.put(file));
} else {
Log.e(LOGTAG, "We should not get an intent with another action!");
handler.gotFile("");
return;
}
}
});
}
boolean handleActivityResult(int requestCode, int resultCode, Intent data) {
ActivityResultHandler handler = mActivityResultHandlerMap.getAndRemove(requestCode);
if (handler != null) {

Просмотреть файл

@ -19,9 +19,17 @@ class CameraImageResultHandler implements ActivityResultHandler {
private static final String LOGTAG = "GeckoCameraImageResultHandler";
private final Queue<String> mFilePickerResult;
private final ActivityHandlerHelper.FileResultHandler mHandler;
CameraImageResultHandler(Queue<String> resultQueue) {
mFilePickerResult = resultQueue;
mHandler = null;
}
/* Use this constructor to asynchronously listen for results */
public CameraImageResultHandler(ActivityHandlerHelper.FileResultHandler handler) {
mHandler = handler;
mFilePickerResult = null;
}
@Override
@ -33,7 +41,12 @@ class CameraImageResultHandler implements ActivityResultHandler {
File file = new File(Environment.getExternalStorageDirectory(), sImageName);
sImageName = "";
mFilePickerResult.offer(file.getAbsolutePath());
if (mFilePickerResult != null)
mFilePickerResult.offer(file.getAbsolutePath());
if (mHandler != null)
mHandler.gotFile(file.getAbsolutePath());
}
// this code is really hacky and doesn't belong anywhere so I'm putting it here for now

Просмотреть файл

@ -18,15 +18,31 @@ class CameraVideoResultHandler implements ActivityResultHandler {
private static final String LOGTAG = "GeckoCameraVideoResultHandler";
private final Queue<String> mFilePickerResult;
private final ActivityHandlerHelper.FileResultHandler mHandler;
CameraVideoResultHandler(Queue<String> resultQueue) {
mFilePickerResult = resultQueue;
mHandler = null;
}
/* Use this constructor to asynchronously listen for results */
public CameraVideoResultHandler(ActivityHandlerHelper.FileResultHandler handler) {
mFilePickerResult = null;
mHandler = handler;
}
private void sendResult(String res) {
if (mFilePickerResult != null)
mFilePickerResult.offer(res);
if (mHandler != null)
mHandler.gotFile(res);
}
@Override
public void onActivityResult(int resultCode, Intent data) {
if (data == null || resultCode != Activity.RESULT_OK) {
mFilePickerResult.offer("");
sendResult("");
return;
}
@ -36,7 +52,7 @@ class CameraVideoResultHandler implements ActivityResultHandler {
null,
null);
cursor.moveToFirst();
mFilePickerResult.offer(cursor.getString(
cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)));
sendResult(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)));
}
}

Просмотреть файл

@ -24,9 +24,11 @@ abstract class FilePickerResultHandler implements ActivityResultHandler {
private static final String LOGTAG = "GeckoFilePickerResultHandler";
protected final Queue<String> mFilePickerResult;
protected final ActivityHandlerHelper.FileResultHandler mHandler;
protected FilePickerResultHandler(Queue<String> resultQueue) {
protected FilePickerResultHandler(Queue<String> resultQueue, ActivityHandlerHelper.FileResultHandler handler) {
mFilePickerResult = resultQueue;
mHandler = handler;
}
protected String handleActivityResult(int resultCode, Intent data) {
@ -53,6 +55,8 @@ abstract class FilePickerResultHandler implements ActivityResultHandler {
cursor.close();
}
}
// tmp filenames must be at least 3 characters long. Add a prefix to make sure that happens
String fileName = "tmp_";
String fileExt = null;
int period;
@ -61,8 +65,9 @@ abstract class FilePickerResultHandler implements ActivityResultHandler {
fileExt = "." + GeckoAppShell.getExtensionFromMimeType(mimeType);
} else {
fileExt = name.substring(period);
fileName = name.substring(0, period);
fileName += name.substring(0, period);
}
Log.i(LOGTAG, "Filename: " + fileName + " . " + fileExt);
File file = File.createTempFile(fileName, fileExt, GeckoLoader.getGREDir(GeckoAppShell.getContext()));
FileOutputStream fos = new FileOutputStream(file);
InputStream is = cr.openInputStream(uri);

Просмотреть файл

@ -13,11 +13,20 @@ class FilePickerResultHandlerSync extends FilePickerResultHandler {
private static final String LOGTAG = "GeckoFilePickerResultHandlerSync";
FilePickerResultHandlerSync(Queue<String> resultQueue) {
super(resultQueue);
super(resultQueue, null);
}
/* Use this constructor to asynchronously listen for results */
public FilePickerResultHandlerSync(ActivityHandlerHelper.FileResultHandler handler) {
super(null, handler);
}
@Override
public void onActivityResult(int resultCode, Intent data) {
mFilePickerResult.offer(handleActivityResult(resultCode, data));
if (mFilePickerResult != null)
mFilePickerResult.offer(handleActivityResult(resultCode, data));
if (mHandler != null)
mHandler.gotFile(handleActivityResult(resultCode, data));
}
}

Просмотреть файл

@ -2499,28 +2499,14 @@ public class GeckoAppShell
return true;
}
static class AsyncResultHandler extends FilePickerResultHandler {
private long mId;
AsyncResultHandler(long id) {
super(null);
mId = id;
}
@Override
public void onActivityResult(int resultCode, Intent data) {
GeckoAppShell.notifyFilePickerResult(handleActivityResult(resultCode, data), mId);
}
}
static native void notifyFilePickerResult(String filePath, long id);
/* Called by JNI from AndroidBridge */
public static void showFilePickerAsync(String aMimeType, long id) {
if (getGeckoInterface() != null)
if (!sActivityHelper.showFilePicker(getGeckoInterface().getActivity(), aMimeType, new AsyncResultHandler(id))) {
GeckoAppShell.notifyFilePickerResult("", id);
public static void showFilePickerAsync(String aMimeType, final long id) {
sActivityHelper.showFilePickerAsync(getGeckoInterface().getActivity(), aMimeType, new ActivityHandlerHelper.FileResultHandler() {
public void gotFile(String filename) {
GeckoAppShell.notifyFilePickerResult(filename, id);
}
});
}
public static void notifyWakeLockChanged(String topic, String state) {

Просмотреть файл

@ -0,0 +1,247 @@
/* 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/. */
const Ci = Components.interfaces;
const Cu = Components.utils;
const Cc = Components.classes;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
function FilePicker() {
}
FilePicker.prototype = {
_mimeTypeFilter: 0,
_extensionsFilter: "",
_defaultString: "",
_domWin: null,
_defaultExtension: null,
_displayDirectory: null,
_filePath: null,
_promptActive: false,
_filterIndex: 0,
init: function(aParent, aTitle, aMode) {
this._domWin = aParent;
Services.obs.addObserver(this, "FilePicker:Result", false);
let idService = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
this.guid = idService.generateUUID().toString();
if (aMode != Ci.nsIFilePicker.modeOpen && aMode != Ci.nsIFilePicker.modeOpenMultiple)
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
appendFilters: function(aFilterMask) {
if (aFilterMask & Ci.nsIFilePicker.filterAudio) {
this._mimeTypeFilter = "audio/*";
return;
}
if (aFilterMask & Ci.nsIFilePicker.filterImages) {
this._mimeTypeFilter = "image/*";
return;
}
if (aFilterMask & Ci.nsIFilePicker.filterVideo) {
this._mimeTypeFilter = "video/*";
return;
}
if (aFilterMask & Ci.nsIFilePicker.filterAll) {
this._mimeTypeFilter = "*/*";
return;
}
/* From BaseFilePicker.cpp */
if (aFilterMask & Ci.nsIFilePicker.filterHTML) {
this.appendFilter("*.html; *.htm; *.shtml; *.xhtml");
}
if (aFilterMask & Ci.nsIFilePicker.filterText) {
this.appendFilter("*.txt; *.text");
}
if (aFilterMask & Ci.nsIFilePicker.filterXML) {
this.appendFilter("*.xml");
}
if (aFilterMask & Ci.nsIFilePicker.xulFilter) {
this.appendFilter("*.xul");
}
if (aFilterMask & Ci.nsIFilePicker.xulFilter) {
this.appendFilter("..apps");
}
},
appendFilter: function(title, filter) {
if (this._extensionsFilter)
this._extensionsFilter += ", ";
this._extensionsFilter += filter;
},
get defaultString() {
return this._defaultString;
},
set defaultString(defaultString) {
this._defaultString = defaultString;
},
get defaultExtension() {
return this._defaultExtension;
},
set defaultExtension(defaultExtension) {
this._defaultExtension = defaultExtension;
},
get filterIndex() {
return this._filterIndex;
},
set filterIndex(val) {
this._filterIndex = val;
},
get displayDirectory() {
return this._displayDirectory;
},
set displayDirectory(dir) {
this._displayDirectory = dir;
},
get file() {
if (!this._filePath) {
return null;
}
return new FileUtils.File(this._filePath);
},
get fileURL() {
let file = this.getFile();
return Services.io.newFileURI(file);
},
get files() {
return this.getEnumerator([this.file], function(file) {
return file;
});
},
get domfile() {
let f = this.file;
if (!f) {
return null;
}
return File(f);
},
get domfiles() {
return this.getEnumerator([this.file], function(file) {
return File(file);
});
},
get addToRecentDocs() {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
set addToRecentDocs(val) {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
show: function() {
if (this._domWin) {
PromptUtils.fireDialogEvent(this._domWin, "DOMWillOpenModalDialog");
let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
callerWin = winUtils.enterModalStateWithWindow();
}
this._promptActive = true;
this._sendMessage();
let thread = Services.tm.currentThread;
while (this._promptActive)
thread.processNextEvent(true);
delete this._promptActive;
if (this._filePath)
return Ci.nsIFilePicker.returnOK;
return Ci.nsIFilePicker.returnCancel;
},
open: function(callback) {
this._callback = callback;
this._sendMessage();
},
_sendMessage: function() {
let msg = {
type: "FilePicker:Show",
guid: this.guid
};
if (!this._extensionsFilter && !this._mimeTypeFilter) {
// If neither filters is set show anything we can.
msg.mode = "mimeType";
msg.mimeType = "*/*";
} else if (this._extensionsFilter) {
msg.mode = "extension";
msg.extensions = this._extensionsFilter;
} else {
msg.mode = "mimeType";
msg.mimeType = this._mimeTypeFilter;
}
this.sendMessageToJava(msg);
},
sendMessageToJava: function(aMsg) {
Cc["@mozilla.org/android/bridge;1"].getService(Ci.nsIAndroidBridge).handleGeckoMessage(JSON.stringify(aMsg));
},
observe: function(aSubject, aTopic, aData) {
let data = JSON.parse(aData);
if (data.guid != this.guid)
return;
this._filePath = null;
if (data.file)
this._filePath = data.file;
this._promptActive = false;
if (this._callback) {
this._callback.done(this._filePath ? Ci.nsIFilePicker.returnOK : Ci.nsIFilePicker.returnCancel);
}
delete this._callback;
},
getEnumerator: function(files, mapFunction) {
return {
QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
mFiles: files,
mIndex: 0,
hasMoreElements: function() {
return (this.mIndex < this.mFiles.length);
},
getNext: function() {
if (this.mIndex >= this.mFiles.length) {
throw Components.results.NS_ERROR_FAILURE;
}
return map(this.mFiles[this.mIndex++]);
}
};
},
classID: Components.ID("{18a4e042-7c7c-424b-a583-354e68553a7f}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker, Ci.nsIObserver])
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FilePicker]);

Просмотреть файл

@ -32,6 +32,7 @@ EXTRA_COMPONENTS = \
NSSDialogService.js \
SiteSpecificUserAgent.js \
PaymentsUI.js \
FilePicker.js \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -102,3 +102,6 @@ contract @mozilla.org/dom/site-specific-user-agent;1 {d5234c9d-0ee2-4b3c-9da3-18
component {3c6c9575-f57e-427b-a8aa-57bc3cbff48f} PaymentsUI.js
contract @mozilla.org/payment/ui-glue;1 {3c6c9575-f57e-427b-a8aa-57bc3cbff48f}
# FilePicker.js
component {18a4e042-7c7c-424b-a583-354e68553a7f} FilePicker.js
contract @mozilla.org/filepicker;1 {18a4e042-7c7c-424b-a583-354e68553a7f}

Просмотреть файл

@ -156,9 +156,6 @@
@BINPATH@/components/exthelper.xpt
@BINPATH@/components/fastfind.xpt
@BINPATH@/components/feeds.xpt
#ifdef MOZ_GTK2
@BINPATH@/components/filepicker.xpt
#endif
@BINPATH@/components/find.xpt
@BINPATH@/components/fuel.xpt
@BINPATH@/components/gfx.xpt
@ -296,10 +293,6 @@
@BINPATH@/components/crypto-SDR.js
@BINPATH@/components/jsconsole-clhandler.manifest
@BINPATH@/components/jsconsole-clhandler.js
#ifdef MOZ_GTK2
@BINPATH@/components/nsFilePicker.manifest
@BINPATH@/components/nsFilePicker.js
#endif
@BINPATH@/components/nsHelperAppDlg.manifest
@BINPATH@/components/nsHelperAppDlg.js
@BINPATH@/components/nsDownloadManagerUI.manifest
@ -351,8 +344,6 @@
@BINPATH@/components/contentAreaDropListener.js
@BINPATH@/components/messageWakeupService.js
@BINPATH@/components/messageWakeupService.manifest
@BINPATH@/components/nsFilePicker.js
@BINPATH@/components/nsFilePicker.manifest
#ifdef MOZ_ENABLE_DBUS
@BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
#endif
@ -559,6 +550,7 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
@BINPATH@/components/ContentPermissionPrompt.js
@BINPATH@/components/DirectoryProvider.js
@BINPATH@/components/DownloadManagerUI.js
@BINPATH@/components/FilePicker.js
@BINPATH@/components/HelperAppDialog.js
@BINPATH@/components/LoginManagerPrompter.js
@BINPATH@/components/MobileComponents.manifest

Просмотреть файл

@ -29,7 +29,6 @@ CPP_SOURCES += [
'nsAppShell.cpp',
'nsClipboard.cpp',
'nsDeviceContextAndroid.cpp',
'nsFilePicker.cpp',
'nsIMEPicker.cpp',
'nsIdleServiceAndroid.cpp',
'nsLookAndFeel.cpp',

Просмотреть файл

@ -1,136 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* 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 "nsFilePicker.h"
#include "AndroidBridge.h"
#include "nsNetUtil.h"
#include "nsIURI.h"
NS_IMPL_ISUPPORTS1(nsFilePicker, nsIFilePicker)
NS_IMETHODIMP nsFilePicker::Init(nsIDOMWindow *parent, const nsAString& title,
int16_t mode)
{
return (mode == nsIFilePicker::modeOpen ||
mode == nsIFilePicker::modeOpenMultiple)
? NS_OK
: NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsFilePicker::AppendFilters(int32_t aFilterMask)
{
if (aFilterMask & filterAudio) {
mMimeTypeFilter.AssignLiteral("audio/*");
return NS_OK;
}
if (aFilterMask & filterImages) {
mMimeTypeFilter.AssignLiteral("image/*");
return NS_OK;
}
if (aFilterMask & filterVideo) {
mMimeTypeFilter.AssignLiteral("video/*");
return NS_OK;
}
if (aFilterMask & filterAll) {
mMimeTypeFilter.AssignLiteral("*/*");
return NS_OK;
}
return nsBaseFilePicker::AppendFilters(aFilterMask);
}
NS_IMETHODIMP nsFilePicker::AppendFilter(const nsAString& /*title*/,
const nsAString& filter)
{
if (!mExtensionsFilter.IsEmpty())
mExtensionsFilter.AppendLiteral(", ");
mExtensionsFilter.Append(filter);
return NS_OK;
}
NS_IMETHODIMP nsFilePicker::GetDefaultString(nsAString & aDefaultString)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsFilePicker::SetDefaultString(const nsAString & aDefaultString)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsFilePicker::GetDefaultExtension(nsAString & aDefaultExtension)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsFilePicker::SetDefaultExtension(const nsAString & aDefaultExtension)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsFilePicker::GetDisplayDirectory(nsIFile **aDisplayDirectory)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsFilePicker::SetDisplayDirectory(nsIFile *aDisplayDirectory)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsFilePicker::GetFile(nsIFile **aFile)
{
NS_ENSURE_ARG_POINTER(aFile);
*aFile = nullptr;
if (mFilePath.IsEmpty()) {
return NS_OK;
}
nsCOMPtr<nsIFile> file(do_CreateInstance("@mozilla.org/file/local;1"));
NS_ENSURE_TRUE(file, NS_ERROR_FAILURE);
file->InitWithPath(mFilePath);
NS_ADDREF(*aFile = file);
nsCString path;
(*aFile)->GetNativePath(path);
return NS_OK;
}
NS_IMETHODIMP nsFilePicker::GetFileURL(nsIURI **aFileURL)
{
nsCOMPtr<nsIFile> file;
GetFile(getter_AddRefs(file));
nsCOMPtr<nsIURI> uri;
NS_NewFileURI(getter_AddRefs(uri), file);
NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
return CallQueryInterface(uri, aFileURL);
}
NS_IMETHODIMP nsFilePicker::Show(int16_t *_retval)
{
if (!mozilla::AndroidBridge::Bridge())
return NS_ERROR_NOT_IMPLEMENTED;
nsAutoString filePath;
if (mExtensionsFilter.IsEmpty() && mMimeTypeFilter.IsEmpty()) {
// If neither filters is set show anything we can.
mozilla::AndroidBridge::Bridge()->ShowFilePickerForMimeType(filePath, NS_LITERAL_STRING("*/*"));
} else if (!mExtensionsFilter.IsEmpty()) {
mozilla::AndroidBridge::Bridge()->ShowFilePickerForExtensions(filePath, mExtensionsFilter);
} else {
mozilla::AndroidBridge::Bridge()->ShowFilePickerForMimeType(filePath, mMimeTypeFilter);
}
*_retval = EmptyString().Equals(filePath) ?
nsIFilePicker::returnCancel : nsIFilePicker::returnOK;
if (*_retval == nsIFilePicker::returnOK)
mFilePath.Assign(filePath);
return NS_OK;
}

Просмотреть файл

@ -1,37 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* 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 NSFILEPICKER_H
#define NSFILEPICKER_H
#include "nsBaseFilePicker.h"
#include "nsString.h"
class nsFilePicker : public nsBaseFilePicker
{
public:
NS_DECL_ISUPPORTS
NS_IMETHODIMP Init(nsIDOMWindow *parent, const nsAString& title,
int16_t mode);
NS_IMETHOD AppendFilters(int32_t aFilterMask);
NS_IMETHOD AppendFilter(const nsAString & aTitle,
const nsAString & aFilter);
NS_IMETHOD GetDefaultString(nsAString & aDefaultString);
NS_IMETHOD SetDefaultString(const nsAString & aDefaultString);
NS_IMETHOD GetDefaultExtension(nsAString & aDefaultExtension);
NS_IMETHOD SetDefaultExtension(const nsAString & aDefaultExtension);
NS_IMETHOD GetFile(nsIFile * *aFile);
NS_IMETHOD GetFileURL(nsIURI * *aFileURL);
NS_IMETHOD SetDisplayDirectory(nsIFile *aDisplayDirectory);
NS_IMETHOD GetDisplayDirectory(nsIFile **aDisplayDirectory);
NS_IMETHOD Show(int16_t *aReturn);
private:
void InitNative(nsIWidget*, const nsAString&, int16_t) {};
nsString mFilePath;
nsString mExtensionsFilter;
nsString mMimeTypeFilter;
};
#endif

Просмотреть файл

@ -22,10 +22,8 @@
#include "nsPrintOptionsAndroid.h"
#include "nsPrintSession.h"
#include "nsDeviceContextAndroid.h"
#include "nsFilePicker.h"
#include "nsHTMLFormatConverter.h"
#include "nsIMEPicker.h"
#include "nsFilePickerProxy.h"
#include "nsXULAppAPI.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
@ -49,24 +47,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(GfxInfo, Init)
}
}
static nsresult
nsFilePickerConstructor(nsISupports *aOuter, REFNSIID aIID,
void **aResult)
{
*aResult = nullptr;
if (aOuter != nullptr) {
return NS_ERROR_NO_AGGREGATION;
}
nsCOMPtr<nsIFilePicker> picker;
if (XRE_GetProcessType() == GeckoProcessType_Content)
picker = new nsFilePickerProxy();
else
picker = new nsFilePicker;
return picker->QueryInterface(aIID, aResult);
}
NS_DEFINE_NAMED_CID(NS_APPSHELL_CID);
NS_DEFINE_NAMED_CID(NS_WINDOW_CID);
NS_DEFINE_NAMED_CID(NS_CHILD_CID);
@ -78,7 +58,6 @@ NS_DEFINE_NAMED_CID(NS_CLIPBOARDHELPER_CID);
NS_DEFINE_NAMED_CID(NS_PRINTSETTINGSSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_PRINTSESSION_CID);
NS_DEFINE_NAMED_CID(NS_DEVICE_CONTEXT_SPEC_CID);
NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID);
NS_DEFINE_NAMED_CID(NS_HTMLFORMATCONVERTER_CID);
NS_DEFINE_NAMED_CID(NS_IMEPICKER_CID);
NS_DEFINE_NAMED_CID(NS_GFXINFO_CID);
@ -96,7 +75,6 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
{ &kNS_PRINTSETTINGSSERVICE_CID, false, NULL, nsPrintOptionsAndroidConstructor },
{ &kNS_PRINTSESSION_CID, false, NULL, nsPrintSessionConstructor },
{ &kNS_DEVICE_CONTEXT_SPEC_CID, false, NULL, nsDeviceContextSpecAndroidConstructor },
{ &kNS_FILEPICKER_CID, false, NULL, nsFilePickerConstructor },
{ &kNS_HTMLFORMATCONVERTER_CID, false, NULL, nsHTMLFormatConverterConstructor },
{ &kNS_IMEPICKER_CID, false, NULL, nsIMEPickerConstructor },
{ &kNS_GFXINFO_CID, false, NULL, mozilla::widget::GfxInfoConstructor },
@ -116,7 +94,6 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
{ "@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID },
{ "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID },
{ "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID },
{ "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID },
{ "@mozilla.org/widget/htmlformatconverter;1", &kNS_HTMLFORMATCONVERTER_CID },
{ "@mozilla.org/imepicker;1", &kNS_IMEPICKER_CID },
{ "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },