diff --git a/embedding/android/GeckoApp.java b/embedding/android/GeckoApp.java index a30dcf4b1951..be6ea0be3389 100644 --- a/embedding/android/GeckoApp.java +++ b/embedding/android/GeckoApp.java @@ -512,10 +512,10 @@ abstract public class GeckoApp static final int FILE_PICKER_REQUEST = 1; private SynchronousQueue mFilePickerResult = new SynchronousQueue(); - public String showFilePicker() { + public String showFilePicker(String aMimeType) { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); - intent.setType("*/*"); + intent.setType(aMimeType); GeckoApp.this. startActivityForResult( Intent.createChooser(intent,"choose a file"), diff --git a/embedding/android/GeckoAppShell.java b/embedding/android/GeckoAppShell.java index 1ab85e7054b1..656908955572 100644 --- a/embedding/android/GeckoAppShell.java +++ b/embedding/android/GeckoAppShell.java @@ -417,8 +417,30 @@ class GeckoAppShell return new Intent(Intent.ACTION_VIEW); } - static String getMimeTypeFromExtension(String aFileExt) { - return android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(aFileExt); + static String getMimeTypeFromExtensions(String aFileExt) { + android.webkit.MimeTypeMap mtm = + android.webkit.MimeTypeMap.getSingleton(); + StringTokenizer st = new StringTokenizer(aFileExt, "., "); + String type = null; + String subType = null; + while (st.hasMoreElements()) { + String ext = st.nextToken(); + String mt = mtm.getMimeTypeFromExtension(ext); + if (mt == null) + continue; + int slash = mt.indexOf('/'); + String tmpType = mt.substring(0, slash); + if (!tmpType.equalsIgnoreCase(type)) + type = type == null ? tmpType : "*"; + String tmpSubType = mt.substring(slash + 1); + if (!tmpSubType.equalsIgnoreCase(subType)) + subType = subType == null ? tmpSubType : "*"; + } + if (type == null) + type = "*"; + if (subType == null) + subType = "*"; + return type + "/" + subType; } static boolean openUriExternal(String aUriSpec, String aMimeType, String aPackageName, @@ -575,7 +597,8 @@ class GeckoAppShell GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics); return metrics.densityDpi; } - public static String showFilePicker() { - return GeckoApp.mAppContext.showFilePicker(); + public static String showFilePicker(String aFilters) { + return GeckoApp.mAppContext. + showFilePicker(getMimeTypeFromExtensions(aFilters)); } } diff --git a/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp b/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp index 3281c0c1a02e..3e2e45538510 100644 --- a/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp +++ b/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp @@ -102,7 +102,7 @@ nsMIMEInfoAndroid::GetMimeInfoForFileExt(const nsACString& aFileExt, nsCString mimeType; if (mozilla::AndroidBridge::Bridge()) mozilla::AndroidBridge::Bridge()-> - GetMimeTypeFromExtension(aFileExt, mimeType); + GetMimeTypeFromExtensions(aFileExt, mimeType); return GetMimeInfoForMimeType(mimeType, aMimeInfo); } diff --git a/widget/src/android/AndroidBridge.cpp b/widget/src/android/AndroidBridge.cpp index 14d6bc4f15f9..9200ed1a0128 100644 --- a/widget/src/android/AndroidBridge.cpp +++ b/widget/src/android/AndroidBridge.cpp @@ -108,12 +108,12 @@ AndroidBridge::Init(JNIEnv *jEnv, jGetHandlersForMimeType = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getHandlersForMimeType", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"); jGetHandlersForProtocol = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getHandlersForProtocol", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"); jOpenUriExternal = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "openUriExternal", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z"); - jGetMimeTypeFromExtension = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getMimeTypeFromExtension", "(Ljava/lang/String;)Ljava/lang/String;"); + jGetMimeTypeFromExtensions = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getMimeTypeFromExtensions", "(Ljava/lang/String;)Ljava/lang/String;"); jMoveTaskToBack = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "moveTaskToBack", "()V"); jGetClipboardText = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getClipboardText", "()Ljava/lang/String;"); jSetClipboardText = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "setClipboardText", "(Ljava/lang/String;)V"); jShowAlertNotification = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "showAlertNotification", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); - jShowFilePicker = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "showFilePicker", "()Ljava/lang/String;"); + jShowFilePicker = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "showFilePicker", "(Ljava/lang/String;)Ljava/lang/String;"); jAlertsProgressListener_OnProgress = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "alertsProgressListener_OnProgress", "(Ljava/lang/String;JJLjava/lang/String;)V"); jAlertsProgressListener_OnCancel = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "alertsProgressListener_OnCancel", "(Ljava/lang/String;)V"); jGetDpi = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getDpi", "()I"); @@ -389,12 +389,12 @@ AndroidBridge::OpenUriExternal(const nsACString& aUriSpec, const nsACString& aMi } void -AndroidBridge::GetMimeTypeFromExtension(const nsACString& aFileExt, nsCString& aMimeType) { +AndroidBridge::GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& aMimeType) { AutoLocalJNIFrame jniFrame; NS_ConvertUTF8toUTF16 wFileExt(aFileExt); jstring jstrExt = mJNIEnv->NewString(wFileExt.get(), wFileExt.Length()); jstring jstrType = static_cast(mJNIEnv->CallStaticObjectMethod(mGeckoAppShellClass, - jGetMimeTypeFromExtension, + jGetMimeTypeFromExtensions, jstrExt)); nsJNIString jniStr(jstrType); aMimeType.Assign(NS_ConvertUTF16toUTF8(jniStr.get())); @@ -506,10 +506,14 @@ AndroidBridge::GetDPI() } void -AndroidBridge::ShowFilePicker(nsAString& aFilePath) +AndroidBridge::ShowFilePicker(nsAString& aFilePath, nsAString& aFilters) { + AutoLocalJNIFrame jniFrame; + jstring jstrFilers = mJNIEnv->NewString(nsPromiseFlatString(aFilters).get(), + aFilters.Length()); jstring jstr = static_cast(mJNIEnv->CallStaticObjectMethod( - mGeckoAppShellClass, jShowFilePicker)); + mGeckoAppShellClass, + jShowFilePicker, jstrFilers)); aFilePath.Assign(nsJNIString(jstr)); } diff --git a/widget/src/android/AndroidBridge.h b/widget/src/android/AndroidBridge.h index b58b2e3d4aa1..ecceed446264 100644 --- a/widget/src/android/AndroidBridge.h +++ b/widget/src/android/AndroidBridge.h @@ -140,7 +140,7 @@ public: const nsAString& aAction = EmptyString(), const nsAString& aTitle = EmptyString()); - void GetMimeTypeFromExtension(const nsACString& aFileExt, nsCString& aMimeType); + void GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& aMimeType); void MoveTaskToBack(); @@ -168,7 +168,7 @@ public: int GetDPI(); - void ShowFilePicker(nsAString& aFilePath); + void ShowFilePicker(nsAString& aFilePath, nsAString& aFilters); struct AutoLocalJNIFrame { AutoLocalJNIFrame(int nEntries = 128) : mEntries(nEntries) { @@ -226,7 +226,7 @@ protected: jmethodID jGetHandlersForMimeType; jmethodID jGetHandlersForProtocol; jmethodID jOpenUriExternal; - jmethodID jGetMimeTypeFromExtension; + jmethodID jGetMimeTypeFromExtensions; jmethodID jMoveTaskToBack; jmethodID jGetClipboardText; jmethodID jSetClipboardText; diff --git a/widget/src/android/nsFilePicker.cpp b/widget/src/android/nsFilePicker.cpp index 34183cc2cb36..a5a7efdf5f67 100644 --- a/widget/src/android/nsFilePicker.cpp +++ b/widget/src/android/nsFilePicker.cpp @@ -48,14 +48,13 @@ NS_IMETHODIMP nsFilePicker::Init(nsIDOMWindow *parent, const nsAString& title, return nsIFilePicker::modeOpen == mode ? NS_OK : NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP nsFilePicker::AppendFilters(PRInt32 filterMask) +NS_IMETHODIMP nsFilePicker::AppendFilter(const nsAString& /*title*/, + const nsAString& filter) { - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP nsFilePicker::AppendFilter(const nsAString & title, const nsAString & filter) -{ - return NS_ERROR_NOT_IMPLEMENTED; + if (!mFilters.IsEmpty()) + mFilters.AppendLiteral(", "); + mFilters.Append(filter); + return NS_OK; } NS_IMETHODIMP nsFilePicker::GetDefaultString(nsAString & aDefaultString) @@ -76,15 +75,6 @@ NS_IMETHODIMP nsFilePicker::SetDefaultExtension(const nsAString & aDefaultExtens return NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP nsFilePicker::GetFilterIndex(PRInt32 *aFilterIndex) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} -NS_IMETHODIMP nsFilePicker::SetFilterIndex(PRInt32 aFilterIndex) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - NS_IMETHODIMP nsFilePicker::GetDisplayDirectory(nsILocalFile **aDisplayDirectory) { return NS_ERROR_NOT_IMPLEMENTED; @@ -127,17 +117,13 @@ NS_IMETHODIMP nsFilePicker::GetFileURL(nsIURI **aFileURL) return CallQueryInterface(uri, aFileURL); } -NS_IMETHODIMP nsFilePicker::GetFiles(nsISimpleEnumerator **aFiles) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - NS_IMETHODIMP nsFilePicker::Show(PRInt16 *_retval NS_OUTPARAM) { if (!mozilla::AndroidBridge::Bridge()) return NS_ERROR_NOT_IMPLEMENTED; nsAutoString filePath; - mozilla::AndroidBridge::Bridge()->ShowFilePicker(filePath); + + mozilla::AndroidBridge::Bridge()->ShowFilePicker(filePath, mFilters); *_retval = EmptyString().Equals(filePath) ? nsIFilePicker::returnCancel : nsIFilePicker::returnOK; if (*_retval == nsIFilePicker::returnOK) diff --git a/widget/src/android/nsFilePicker.h b/widget/src/android/nsFilePicker.h index 32ae8938742d..13af1c9cddba 100644 --- a/widget/src/android/nsFilePicker.h +++ b/widget/src/android/nsFilePicker.h @@ -38,16 +38,30 @@ #ifndef NSFILEPICKER_H #define NSFILEPICKER_H -#include "nsIFilePicker.h" +#include "nsBaseFilePicker.h" #include "nsString.h" -class nsFilePicker : public nsIFilePicker +class nsFilePicker : public nsBaseFilePicker { public: - NS_DECL_ISUPPORTS - NS_DECL_NSIFILEPICKER + NS_DECL_ISUPPORTS + NS_IMETHODIMP Init(nsIDOMWindow *parent, const nsAString& title, + PRInt16 mode); + 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(nsILocalFile * *aFile); + NS_IMETHOD GetFileURL(nsIURI * *aFileURL); + NS_IMETHOD SetDisplayDirectory(nsILocalFile *aDisplayDirectory); + NS_IMETHOD GetDisplayDirectory(nsILocalFile **aDisplayDirectory); + NS_IMETHOD Show(PRInt16 *aReturn); private: - nsString mFilePath; + void InitNative(nsIWidget*, const nsAString&, PRInt16) {}; + nsString mFilePath; + nsString mFilters; }; #endif