summaryrefslogtreecommitdiffstats
path: root/uriloader/exthandler/android
diff options
context:
space:
mode:
Diffstat (limited to 'uriloader/exthandler/android')
-rw-r--r--uriloader/exthandler/android/nsAndroidHandlerApp.cpp91
-rw-r--r--uriloader/exthandler/android/nsAndroidHandlerApp.h33
-rw-r--r--uriloader/exthandler/android/nsExternalSharingAppService.cpp61
-rw-r--r--uriloader/exthandler/android/nsExternalSharingAppService.h28
-rw-r--r--uriloader/exthandler/android/nsExternalURLHandlerService.cpp27
-rw-r--r--uriloader/exthandler/android/nsExternalURLHandlerService.h27
-rw-r--r--uriloader/exthandler/android/nsMIMEInfoAndroid.cpp427
-rw-r--r--uriloader/exthandler/android/nsMIMEInfoAndroid.h60
-rw-r--r--uriloader/exthandler/android/nsOSHelperAppService.cpp67
-rw-r--r--uriloader/exthandler/android/nsOSHelperAppService.h40
10 files changed, 861 insertions, 0 deletions
diff --git a/uriloader/exthandler/android/nsAndroidHandlerApp.cpp b/uriloader/exthandler/android/nsAndroidHandlerApp.cpp
new file mode 100644
index 000000000..4c7ffff48
--- /dev/null
+++ b/uriloader/exthandler/android/nsAndroidHandlerApp.cpp
@@ -0,0 +1,91 @@
+/* -*- Mode: c++; c-basic-offset: 2; 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 "nsAndroidHandlerApp.h"
+#include "GeneratedJNIWrappers.h"
+
+using namespace mozilla;
+
+
+NS_IMPL_ISUPPORTS(nsAndroidHandlerApp, nsIHandlerApp, nsISharingHandlerApp)
+
+nsAndroidHandlerApp::nsAndroidHandlerApp(const nsAString& aName,
+ const nsAString& aDescription,
+ const nsAString& aPackageName,
+ const nsAString& aClassName,
+ const nsACString& aMimeType,
+ const nsAString& aAction) :
+mName(aName), mDescription(aDescription), mPackageName(aPackageName),
+ mClassName(aClassName), mMimeType(aMimeType), mAction(aAction)
+{
+}
+
+nsAndroidHandlerApp::~nsAndroidHandlerApp()
+{
+}
+
+NS_IMETHODIMP
+nsAndroidHandlerApp::GetName(nsAString & aName)
+{
+ aName.Assign(mName);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAndroidHandlerApp::SetName(const nsAString & aName)
+{
+ mName.Assign(aName);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAndroidHandlerApp::GetDetailedDescription(nsAString & aDescription)
+{
+ aDescription.Assign(mDescription);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAndroidHandlerApp::SetDetailedDescription(const nsAString & aDescription)
+{
+ mDescription.Assign(aDescription);
+
+ return NS_OK;
+}
+
+// XXX Workaround for bug 986975 to maintain the existing broken semantics
+template<>
+struct nsISharingHandlerApp::COMTypeInfo<nsAndroidHandlerApp, void> {
+ static const nsIID kIID;
+};
+const nsIID nsISharingHandlerApp::COMTypeInfo<nsAndroidHandlerApp, void>::kIID = NS_IHANDLERAPP_IID;
+
+NS_IMETHODIMP
+nsAndroidHandlerApp::Equals(nsIHandlerApp *aHandlerApp, bool *aRetval)
+{
+ nsCOMPtr<nsAndroidHandlerApp> aApp = do_QueryInterface(aHandlerApp);
+ *aRetval = aApp && aApp->mName.Equals(mName) &&
+ aApp->mDescription.Equals(mDescription);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAndroidHandlerApp::LaunchWithURI(nsIURI *aURI, nsIInterfaceRequestor *aWindowContext)
+{
+ nsCString uriSpec;
+ aURI->GetSpec(uriSpec);
+ return java::GeckoAppShell::OpenUriExternal(
+ uriSpec, mMimeType, mPackageName, mClassName,
+ mAction, EmptyString()) ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsAndroidHandlerApp::Share(const nsAString & data, const nsAString & title)
+{
+ return java::GeckoAppShell::OpenUriExternal(
+ data, mMimeType, mPackageName, mClassName,
+ mAction, EmptyString()) ? NS_OK : NS_ERROR_FAILURE;
+}
+
diff --git a/uriloader/exthandler/android/nsAndroidHandlerApp.h b/uriloader/exthandler/android/nsAndroidHandlerApp.h
new file mode 100644
index 000000000..bb3872463
--- /dev/null
+++ b/uriloader/exthandler/android/nsAndroidHandlerApp.h
@@ -0,0 +1,33 @@
+/* -*- 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 nsAndroidHandlerApp_h
+#define nsAndroidHandlerApp_h
+
+#include "nsMIMEInfoImpl.h"
+#include "nsIExternalSharingAppService.h"
+
+class nsAndroidHandlerApp : public nsISharingHandlerApp {
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIHANDLERAPP
+ NS_DECL_NSISHARINGHANDLERAPP
+
+ nsAndroidHandlerApp(const nsAString& aName, const nsAString& aDescription,
+ const nsAString& aPackageName,
+ const nsAString& aClassName,
+ const nsACString& aMimeType, const nsAString& aAction);
+
+private:
+ virtual ~nsAndroidHandlerApp();
+
+ nsString mName;
+ nsString mDescription;
+ nsString mPackageName;
+ nsString mClassName;
+ nsCString mMimeType;
+ nsString mAction;
+};
+#endif
diff --git a/uriloader/exthandler/android/nsExternalSharingAppService.cpp b/uriloader/exthandler/android/nsExternalSharingAppService.cpp
new file mode 100644
index 000000000..f4f8a7013
--- /dev/null
+++ b/uriloader/exthandler/android/nsExternalSharingAppService.cpp
@@ -0,0 +1,61 @@
+/* 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 "nsExternalSharingAppService.h"
+
+#include "mozilla/ModuleUtils.h"
+#include "nsIClassInfoImpl.h"
+
+#include "AndroidBridge.h"
+#include "nsArrayUtils.h"
+#include "nsISupportsUtils.h"
+#include "nsComponentManagerUtils.h"
+
+using namespace mozilla;
+
+NS_IMPL_ISUPPORTS(nsExternalSharingAppService, nsIExternalSharingAppService)
+
+nsExternalSharingAppService::nsExternalSharingAppService()
+{
+}
+
+nsExternalSharingAppService::~nsExternalSharingAppService()
+{
+}
+
+NS_IMETHODIMP
+nsExternalSharingAppService::ShareWithDefault(const nsAString & data,
+ const nsAString & mime,
+ const nsAString & title)
+{
+ NS_NAMED_LITERAL_STRING(sendAction, "android.intent.action.SEND");
+ const nsString emptyString = EmptyString();
+ return java::GeckoAppShell::OpenUriExternal(data,
+ mime, emptyString, emptyString, sendAction, title) ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsExternalSharingAppService::GetSharingApps(const nsAString & aMIMEType,
+ uint32_t *aLen,
+ nsISharingHandlerApp ***aHandlers)
+{
+ nsresult rv;
+ NS_NAMED_LITERAL_STRING(sendAction, "android.intent.action.SEND");
+ nsCOMPtr<nsIMutableArray> array = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!AndroidBridge::Bridge())
+ return NS_OK;
+ AndroidBridge::Bridge()->GetHandlersForMimeType(aMIMEType, array,
+ nullptr, sendAction);
+ array->GetLength(aLen);
+ *aHandlers =
+ static_cast<nsISharingHandlerApp**>(moz_xmalloc(sizeof(nsISharingHandlerApp*)
+ * *aLen));
+ for (uint32_t i = 0; i < *aLen; i++) {
+ rv = array->QueryElementAt(i, NS_GET_IID(nsISharingHandlerApp),
+ (void**)(*aHandlers + i));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ return NS_OK;
+}
diff --git a/uriloader/exthandler/android/nsExternalSharingAppService.h b/uriloader/exthandler/android/nsExternalSharingAppService.h
new file mode 100644
index 000000000..a1e2e4363
--- /dev/null
+++ b/uriloader/exthandler/android/nsExternalSharingAppService.h
@@ -0,0 +1,28 @@
+/* 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 NS_EXTERNAL_SHARING_APP_SERVICE_H
+#define NS_EXTERNAL_SHARING_APP_SERVICE_H
+#include "nsIExternalSharingAppService.h"
+
+
+#define NS_EXTERNALSHARINGAPPSERVICE_CID \
+ {0x93e2c46e, 0x0011, 0x434b, \
+ {0x81, 0x2e, 0xb6, 0xf3, 0xa8, 0x1e, 0x2a, 0x58}}
+
+class nsExternalSharingAppService final
+ : public nsIExternalSharingAppService
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIEXTERNALSHARINGAPPSERVICE
+
+ nsExternalSharingAppService();
+
+private:
+ ~nsExternalSharingAppService();
+
+};
+
+#endif /*NS_EXTERNAL_SHARING_APP_SERVICE_H */
diff --git a/uriloader/exthandler/android/nsExternalURLHandlerService.cpp b/uriloader/exthandler/android/nsExternalURLHandlerService.cpp
new file mode 100644
index 000000000..f417b5b9f
--- /dev/null
+++ b/uriloader/exthandler/android/nsExternalURLHandlerService.cpp
@@ -0,0 +1,27 @@
+/* -*- Mode: c++; c-basic-offset: 2; 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 "nsExternalURLHandlerService.h"
+#include "nsMIMEInfoAndroid.h"
+
+NS_IMPL_ISUPPORTS(nsExternalURLHandlerService, nsIExternalURLHandlerService)
+
+nsExternalURLHandlerService::nsExternalURLHandlerService()
+{
+}
+
+nsExternalURLHandlerService::~nsExternalURLHandlerService()
+{
+}
+
+NS_IMETHODIMP
+nsExternalURLHandlerService::GetURLHandlerInfoFromOS(nsIURI *aURL,
+ bool *found,
+ nsIHandlerInfo **info)
+{
+ nsCString uriSpec;
+ aURL->GetSpec(uriSpec);
+ return nsMIMEInfoAndroid::GetMimeInfoForURL(uriSpec, found, info);
+}
diff --git a/uriloader/exthandler/android/nsExternalURLHandlerService.h b/uriloader/exthandler/android/nsExternalURLHandlerService.h
new file mode 100644
index 000000000..f2618c7e6
--- /dev/null
+++ b/uriloader/exthandler/android/nsExternalURLHandlerService.h
@@ -0,0 +1,27 @@
+/* -*- 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 NSEXTERNALURLHANDLERSERVICE_H
+#define NSEXTERNALURLHANDLERSERVICE_H
+
+#include "nsIExternalURLHandlerService.h"
+
+// {4BF1F8EF-D947-4BA3-9CD3-8C9A54A63A1C}
+#define NS_EXTERNALURLHANDLERSERVICE_CID \
+ {0x4bf1f8ef, 0xd947, 0x4ba3, {0x9c, 0xd3, 0x8c, 0x9a, 0x54, 0xa6, 0x3a, 0x1c}}
+
+class nsExternalURLHandlerService final
+ : public nsIExternalURLHandlerService
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIEXTERNALURLHANDLERSERVICE
+
+ nsExternalURLHandlerService();
+private:
+ ~nsExternalURLHandlerService();
+};
+
+#endif // NSEXTERNALURLHANDLERSERVICE_H
diff --git a/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp b/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp
new file mode 100644
index 000000000..ee9bc8570
--- /dev/null
+++ b/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp
@@ -0,0 +1,427 @@
+/* -*- Mode: c++; c-basic-offset: 2; 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 "nsMIMEInfoAndroid.h"
+#include "AndroidBridge.h"
+#include "nsAndroidHandlerApp.h"
+#include "nsArrayUtils.h"
+#include "nsISupportsUtils.h"
+#include "nsStringEnumerator.h"
+#include "nsNetUtil.h"
+
+using namespace mozilla;
+
+NS_IMPL_ISUPPORTS(nsMIMEInfoAndroid, nsIMIMEInfo, nsIHandlerInfo)
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::LaunchDefaultWithFile(nsIFile* aFile)
+{
+ return LaunchWithFile(aFile);
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::LoadUriInternal(nsIURI * aURI)
+{
+ nsCString uriSpec;
+ aURI->GetSpec(uriSpec);
+
+ nsCString uriScheme;
+ aURI->GetScheme(uriScheme);
+
+ nsAutoString mimeType;
+ if (mType.Equals(uriScheme) || mType.Equals(uriSpec)) {
+ mimeType = EmptyString();
+ } else {
+ mimeType = NS_ConvertUTF8toUTF16(mType);
+ }
+
+ if (java::GeckoAppShell::OpenUriExternal(
+ NS_ConvertUTF8toUTF16(uriSpec), mimeType, EmptyString(),
+ EmptyString(), EmptyString(), EmptyString())) {
+ return NS_OK;
+ }
+ return NS_ERROR_FAILURE;
+}
+
+bool
+nsMIMEInfoAndroid::GetMimeInfoForMimeType(const nsACString& aMimeType,
+ nsMIMEInfoAndroid** aMimeInfo)
+{
+ RefPtr<nsMIMEInfoAndroid> info = new nsMIMEInfoAndroid(aMimeType);
+ mozilla::AndroidBridge* bridge = mozilla::AndroidBridge::Bridge();
+ // we don't have access to the bridge, so just assume we can handle
+ // the mime type for now and let the system deal with it
+ if (!bridge){
+ info.forget(aMimeInfo);
+ return false;
+ }
+
+ nsIHandlerApp* systemDefault = nullptr;
+
+ if (!IsUTF8(aMimeType, true))
+ return false;
+
+ NS_ConvertUTF8toUTF16 mimeType(aMimeType);
+
+ bridge->GetHandlersForMimeType(mimeType,
+ info->mHandlerApps, &systemDefault);
+
+ if (systemDefault)
+ info->mPrefApp = systemDefault;
+
+ nsAutoCString fileExt;
+ bridge->GetExtensionFromMimeType(aMimeType, fileExt);
+ info->SetPrimaryExtension(fileExt);
+
+ uint32_t len;
+ info->mHandlerApps->GetLength(&len);
+ if (len == 1) {
+ info.forget(aMimeInfo);
+ return false;
+ }
+
+ info.forget(aMimeInfo);
+ return true;
+}
+
+bool
+nsMIMEInfoAndroid::GetMimeInfoForFileExt(const nsACString& aFileExt,
+ nsMIMEInfoAndroid **aMimeInfo)
+{
+ nsCString mimeType;
+ if (mozilla::AndroidBridge::Bridge())
+ mozilla::AndroidBridge::Bridge()->
+ GetMimeTypeFromExtensions(aFileExt, mimeType);
+
+ // "*/*" means that the bridge didn't know.
+ if (mimeType.Equals(nsDependentCString("*/*"), nsCaseInsensitiveCStringComparator()))
+ return false;
+
+ bool found = GetMimeInfoForMimeType(mimeType, aMimeInfo);
+ (*aMimeInfo)->SetPrimaryExtension(aFileExt);
+ return found;
+}
+
+/**
+ * Returns MIME info for the aURL, which may contain the whole URL or only a protocol
+ */
+nsresult
+nsMIMEInfoAndroid::GetMimeInfoForURL(const nsACString &aURL,
+ bool *found,
+ nsIHandlerInfo **info)
+{
+ nsMIMEInfoAndroid *mimeinfo = new nsMIMEInfoAndroid(aURL);
+ NS_ADDREF(*info = mimeinfo);
+ *found = true;
+
+ mozilla::AndroidBridge* bridge = mozilla::AndroidBridge::Bridge();
+ if (!bridge) {
+ // we don't have access to the bridge, so just assume we can handle
+ // the protocol for now and let the system deal with it
+ return NS_OK;
+ }
+
+ nsIHandlerApp* systemDefault = nullptr;
+ bridge->GetHandlersForURL(NS_ConvertUTF8toUTF16(aURL),
+ mimeinfo->mHandlerApps, &systemDefault);
+
+ if (systemDefault)
+ mimeinfo->mPrefApp = systemDefault;
+
+
+ nsAutoCString fileExt;
+ nsAutoCString mimeType;
+ mimeinfo->GetType(mimeType);
+ bridge->GetExtensionFromMimeType(mimeType, fileExt);
+ mimeinfo->SetPrimaryExtension(fileExt);
+
+ uint32_t len;
+ mimeinfo->mHandlerApps->GetLength(&len);
+ if (len == 1) {
+ // Code that calls this requires an object regardless if the OS has
+ // something for us, so we return the empty object.
+ *found = false;
+ return NS_OK;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::GetType(nsACString& aType)
+{
+ aType.Assign(mType);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::GetDescription(nsAString& aDesc)
+{
+ aDesc.Assign(mDescription);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::SetDescription(const nsAString& aDesc)
+{
+ mDescription.Assign(aDesc);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::GetPreferredApplicationHandler(nsIHandlerApp** aApp)
+{
+ *aApp = mPrefApp;
+ NS_IF_ADDREF(*aApp);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::SetPreferredApplicationHandler(nsIHandlerApp* aApp)
+{
+ mPrefApp = aApp;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::GetPossibleApplicationHandlers(nsIMutableArray **aHandlerApps)
+{
+ if (!mHandlerApps)
+ mHandlerApps = do_CreateInstance(NS_ARRAY_CONTRACTID);
+
+ if (!mHandlerApps)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ *aHandlerApps = mHandlerApps;
+ NS_IF_ADDREF(*aHandlerApps);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::GetHasDefaultHandler(bool* aHasDefault)
+{
+ uint32_t len;
+ *aHasDefault = false;
+ if (!mHandlerApps)
+ return NS_OK;
+
+ if (NS_FAILED(mHandlerApps->GetLength(&len)))
+ return NS_OK;
+
+ if (len == 0)
+ return NS_OK;
+
+ *aHasDefault = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::GetDefaultDescription(nsAString& aDesc)
+{
+ aDesc.Assign(EmptyString());
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::LaunchWithURI(nsIURI* aURI, nsIInterfaceRequestor* req)
+{
+ return mPrefApp->LaunchWithURI(aURI, req);
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::GetPreferredAction(nsHandlerInfoAction* aPrefAction)
+{
+ *aPrefAction = mPrefAction;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::SetPreferredAction(nsHandlerInfoAction aPrefAction)
+{
+ mPrefAction = aPrefAction;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::GetAlwaysAskBeforeHandling(bool* aAlwaysAsk)
+{
+ *aAlwaysAsk = mAlwaysAsk;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::SetAlwaysAskBeforeHandling(bool aAlwaysAsk)
+{
+ mAlwaysAsk = aAlwaysAsk;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::GetFileExtensions(nsIUTF8StringEnumerator** aResult)
+{
+ return NS_NewUTF8StringEnumerator(aResult, &mExtensions, this);
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::SetFileExtensions(const nsACString & aExtensions)
+{
+ mExtensions.Clear();
+ nsCString extList(aExtensions);
+
+ int32_t breakLocation = -1;
+ while ( (breakLocation = extList.FindChar(',')) != -1)
+ {
+ mExtensions.AppendElement(Substring(extList.get(), extList.get() + breakLocation));
+ extList.Cut(0, breakLocation + 1);
+ }
+ if (!extList.IsEmpty())
+ mExtensions.AppendElement(extList);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::ExtensionExists(const nsACString & aExtension, bool *aRetVal)
+{
+ NS_ASSERTION(!aExtension.IsEmpty(), "no extension");
+
+ nsCString mimeType;
+ if (mozilla::AndroidBridge::Bridge()) {
+ mozilla::AndroidBridge::Bridge()->
+ GetMimeTypeFromExtensions(aExtension, mimeType);
+ }
+
+ // "*/*" means the bridge didn't find anything (i.e., extension doesn't exist).
+ *aRetVal = !mimeType.Equals(nsDependentCString("*/*"), nsCaseInsensitiveCStringComparator());
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::AppendExtension(const nsACString & aExtension)
+{
+ mExtensions.AppendElement(aExtension);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::GetPrimaryExtension(nsACString & aPrimaryExtension)
+{
+ if (!mExtensions.Length())
+ return NS_ERROR_NOT_INITIALIZED;
+
+ aPrimaryExtension = mExtensions[0];
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::SetPrimaryExtension(const nsACString & aExtension)
+{
+ uint32_t extCount = mExtensions.Length();
+ uint8_t i;
+ bool found = false;
+ for (i=0; i < extCount; i++) {
+ const nsCString& ext = mExtensions[i];
+ if (ext.Equals(aExtension, nsCaseInsensitiveCStringComparator())) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ mExtensions.RemoveElementAt(i);
+ }
+
+ mExtensions.InsertElementAt(0, aExtension);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::GetMIMEType(nsACString & aMIMEType)
+{
+ aMIMEType.Assign(mType);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::Equals(nsIMIMEInfo *aMIMEInfo, bool *aRetVal)
+{
+ if (!aMIMEInfo) return NS_ERROR_NULL_POINTER;
+
+ nsAutoCString type;
+ nsresult rv = aMIMEInfo->GetMIMEType(type);
+ if (NS_FAILED(rv)) return rv;
+
+ *aRetVal = mType.Equals(type);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::GetPossibleLocalHandlers(nsIArray * *aPossibleLocalHandlers)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoAndroid::LaunchWithFile(nsIFile *aFile)
+{
+ nsCOMPtr<nsIURI> uri;
+ NS_NewFileURI(getter_AddRefs(uri), aFile);
+ return LoadUriInternal(uri);
+}
+
+nsMIMEInfoAndroid::nsMIMEInfoAndroid(const nsACString& aMIMEType) :
+ mType(aMIMEType), mAlwaysAsk(true),
+ mPrefAction(nsIMIMEInfo::useHelperApp)
+{
+ mPrefApp = new nsMIMEInfoAndroid::SystemChooser(this);
+ nsresult rv;
+ mHandlerApps = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+ mHandlerApps->AppendElement(mPrefApp, false);
+}
+
+NS_IMPL_ISUPPORTS(nsMIMEInfoAndroid::SystemChooser, nsIHandlerApp)
+
+
+nsresult nsMIMEInfoAndroid::SystemChooser::GetName(nsAString & aName) {
+ aName.AssignLiteral(u"Android chooser");
+ return NS_OK;
+}
+
+nsresult
+nsMIMEInfoAndroid::SystemChooser::SetName(const nsAString&) {
+ return NS_OK;
+}
+
+nsresult
+nsMIMEInfoAndroid::SystemChooser::GetDetailedDescription(nsAString & aDesc) {
+ aDesc.AssignLiteral(u"Android's default handler application chooser");
+ return NS_OK;
+}
+
+nsresult
+nsMIMEInfoAndroid::SystemChooser::SetDetailedDescription(const nsAString&) {
+ return NS_OK;
+}
+
+// XXX Workaround for bug 986975 to maintain the existing broken semantics
+template<>
+struct nsIHandlerApp::COMTypeInfo<nsMIMEInfoAndroid::SystemChooser, void> {
+ static const nsIID kIID;
+};
+const nsIID nsIHandlerApp::COMTypeInfo<nsMIMEInfoAndroid::SystemChooser, void>::kIID = NS_IHANDLERAPP_IID;
+
+nsresult
+nsMIMEInfoAndroid::SystemChooser::Equals(nsIHandlerApp *aHandlerApp, bool *aRetVal) {
+ nsCOMPtr<nsMIMEInfoAndroid::SystemChooser> info = do_QueryInterface(aHandlerApp);
+ if (info)
+ return mOuter->Equals(info->mOuter, aRetVal);
+ *aRetVal = false;
+ return NS_OK;
+}
+
+nsresult
+nsMIMEInfoAndroid::SystemChooser::LaunchWithURI(nsIURI* aURI, nsIInterfaceRequestor*)
+{
+ return mOuter->LoadUriInternal(aURI);
+}
diff --git a/uriloader/exthandler/android/nsMIMEInfoAndroid.h b/uriloader/exthandler/android/nsMIMEInfoAndroid.h
new file mode 100644
index 000000000..569d715bd
--- /dev/null
+++ b/uriloader/exthandler/android/nsMIMEInfoAndroid.h
@@ -0,0 +1,60 @@
+/* -*- Mode: c++; c-basic-offset: 2; 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 nsMIMEInfoAndroid_h
+#define nsMIMEInfoAndroid_h
+
+#include "nsMIMEInfoImpl.h"
+#include "nsIMutableArray.h"
+#include "nsAndroidHandlerApp.h"
+
+class nsMIMEInfoAndroid final : public nsIMIMEInfo
+{
+public:
+ static MOZ_MUST_USE bool
+ GetMimeInfoForMimeType(const nsACString& aMimeType,
+ nsMIMEInfoAndroid** aMimeInfo);
+ static MOZ_MUST_USE bool
+ GetMimeInfoForFileExt(const nsACString& aFileExt,
+ nsMIMEInfoAndroid** aMimeInfo);
+
+ static MOZ_MUST_USE nsresult
+ GetMimeInfoForURL(const nsACString &aURL, bool *found,
+ nsIHandlerInfo **info);
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIMIMEINFO
+ NS_DECL_NSIHANDLERINFO
+
+ nsMIMEInfoAndroid(const nsACString& aMIMEType);
+
+private:
+ ~nsMIMEInfoAndroid() {}
+
+ virtual MOZ_MUST_USE nsresult LaunchDefaultWithFile(nsIFile* aFile);
+ virtual MOZ_MUST_USE nsresult LoadUriInternal(nsIURI *aURI);
+ nsCOMPtr<nsIMutableArray> mHandlerApps;
+ nsCString mType;
+ nsTArray<nsCString> mExtensions;
+ bool mAlwaysAsk;
+ nsHandlerInfoAction mPrefAction;
+ nsString mDescription;
+ nsCOMPtr<nsIHandlerApp> mPrefApp;
+
+public:
+ class SystemChooser final : public nsIHandlerApp {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIHANDLERAPP
+ SystemChooser(nsMIMEInfoAndroid* aOuter): mOuter(aOuter) {}
+
+ private:
+ ~SystemChooser() {}
+
+ nsMIMEInfoAndroid* mOuter;
+ };
+};
+
+#endif /* nsMIMEInfoAndroid_h */
diff --git a/uriloader/exthandler/android/nsOSHelperAppService.cpp b/uriloader/exthandler/android/nsOSHelperAppService.cpp
new file mode 100644
index 000000000..3a170dcf6
--- /dev/null
+++ b/uriloader/exthandler/android/nsOSHelperAppService.cpp
@@ -0,0 +1,67 @@
+/* -*- 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 "nsOSHelperAppService.h"
+#include "nsMIMEInfoAndroid.h"
+#include "AndroidBridge.h"
+
+nsOSHelperAppService::nsOSHelperAppService() : nsExternalHelperAppService()
+{
+}
+
+nsOSHelperAppService::~nsOSHelperAppService()
+{
+}
+
+already_AddRefed<nsIMIMEInfo>
+nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
+ const nsACString& aFileExt,
+ bool* aFound)
+{
+ RefPtr<nsMIMEInfoAndroid> mimeInfo;
+ *aFound = false;
+ if (!aMIMEType.IsEmpty())
+ *aFound =
+ nsMIMEInfoAndroid::GetMimeInfoForMimeType(aMIMEType,
+ getter_AddRefs(mimeInfo));
+ if (!*aFound)
+ *aFound =
+ nsMIMEInfoAndroid::GetMimeInfoForFileExt(aFileExt,
+ getter_AddRefs(mimeInfo));
+
+ // Code that calls this requires an object regardless if the OS has
+ // something for us, so we return the empty object.
+ if (!*aFound)
+ mimeInfo = new nsMIMEInfoAndroid(aMIMEType);
+
+ return mimeInfo.forget();
+}
+
+nsresult
+nsOSHelperAppService::OSProtocolHandlerExists(const char* aScheme,
+ bool* aExists)
+{
+ *aExists = mozilla::AndroidBridge::Bridge()->GetHandlersForURL(NS_ConvertUTF8toUTF16(aScheme));
+ return NS_OK;
+}
+
+nsresult nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const nsACString &aScheme,
+ bool *found,
+ nsIHandlerInfo **info)
+{
+ return nsMIMEInfoAndroid::GetMimeInfoForURL(aScheme, found, info);
+}
+
+nsIHandlerApp*
+nsOSHelperAppService::CreateAndroidHandlerApp(const nsAString& aName,
+ const nsAString& aDescription,
+ const nsAString& aPackageName,
+ const nsAString& aClassName,
+ const nsACString& aMimeType,
+ const nsAString& aAction)
+{
+ return new nsAndroidHandlerApp(aName, aDescription, aPackageName,
+ aClassName, aMimeType, aAction);
+}
diff --git a/uriloader/exthandler/android/nsOSHelperAppService.h b/uriloader/exthandler/android/nsOSHelperAppService.h
new file mode 100644
index 000000000..4f3623894
--- /dev/null
+++ b/uriloader/exthandler/android/nsOSHelperAppService.h
@@ -0,0 +1,40 @@
+/* -*- 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 nsOSHelperAppService_h
+#define nsOSHelperAppService_h
+
+#include "nsCExternalHandlerService.h"
+#include "nsExternalHelperAppService.h"
+
+class nsOSHelperAppService : public nsExternalHelperAppService
+{
+public:
+ nsOSHelperAppService();
+ virtual ~nsOSHelperAppService();
+
+ virtual already_AddRefed<nsIMIMEInfo>
+ GetMIMEInfoFromOS(const nsACString& aMIMEType,
+ const nsACString& aFileExt,
+ bool* aFound);
+
+ virtual MOZ_MUST_USE nsresult
+ OSProtocolHandlerExists(const char* aScheme,
+ bool* aExists);
+
+ NS_IMETHOD GetProtocolHandlerInfoFromOS(const nsACString &aScheme,
+ bool *found,
+ nsIHandlerInfo **_retval);
+
+ static nsIHandlerApp*
+ CreateAndroidHandlerApp(const nsAString& aName,
+ const nsAString& aDescription,
+ const nsAString& aPackageName,
+ const nsAString& aClassName,
+ const nsACString& aMimeType,
+ const nsAString& aAction = EmptyString());
+};
+
+#endif /* nsOSHelperAppService_h */