bug 582616 - Sharing back-end for Android r=mwu,mfinkle sr=stuart a=blocking-fennec

This commit is contained in:
Brad Lassey 2010-09-30 11:37:36 -04:00
parent 31a00d810d
commit 854d433e01
20 changed files with 435 additions and 107 deletions

View File

@ -57,6 +57,9 @@
#ifdef MOZ_ENABLE_DBUS
#include "nsDBusHandlerApp.h"
#endif
#ifdef ANDROID
#include "nsExternalSharingAppService.h"
#endif
// session history
#include "nsSHEntry.h"
@ -110,6 +113,9 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(PlatformLocalHandlerApp_t)
#ifdef MOZ_ENABLE_DBUS
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDBusHandlerApp)
#endif
#ifdef ANDROID
NS_GENERIC_FACTORY_CONSTRUCTOR(nsExternalSharingAppService)
#endif
// session history
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHEntry)
@ -134,6 +140,9 @@ NS_DEFINE_NAMED_CID(NS_LOCALHANDLERAPP_CID);
#ifdef MOZ_ENABLE_DBUS
NS_DEFINE_NAMED_CID(NS_DBUSHANDLERAPP_CID);
#endif
#ifdef ANDROID
NS_DEFINE_NAMED_CID(NS_EXTERNALSHARINGAPPSERVICE_CID);
#endif
NS_DEFINE_NAMED_CID(NS_SHENTRY_CID);
NS_DEFINE_NAMED_CID(NS_HISTORYENTRY_CID);
NS_DEFINE_NAMED_CID(NS_SHTRANSACTION_CID);
@ -157,6 +166,9 @@ const mozilla::Module::CIDEntry kDocShellCIDs[] = {
{ &kNS_LOCALHANDLERAPP_CID, false, NULL, PlatformLocalHandlerApp_tConstructor },
#ifdef MOZ_ENABLE_DBUS
{ &kNS_DBUSHANDLERAPP_CID, false, NULL, nsDBusHandlerAppConstructor },
#endif
#ifdef ANDROID
{ &kNS_EXTERNALSHARINGAPPSERVICE_CID, false, NULL, nsExternalSharingAppServiceConstructor },
#endif
{ &kNS_SHENTRY_CID, false, NULL, nsSHEntryConstructor },
{ &kNS_HISTORYENTRY_CID, false, NULL, nsSHEntryConstructor },
@ -198,6 +210,9 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = {
{ NS_LOCALHANDLERAPP_CONTRACTID, &kNS_LOCALHANDLERAPP_CID },
#ifdef MOZ_ENABLE_DBUS
{ NS_DBUSHANDLERAPP_CONTRACTID, &kNS_DBUSHANDLERAPP_CID },
#endif
#ifdef ANDROID
{ NS_EXTERNALSHARINGAPPSERVICE_CONTRACTID, &kNS_EXTERNALSHARINGAPPSERVICE_CID },
#endif
{ NS_SHENTRY_CONTRACTID, &kNS_SHENTRY_CID },
{ NS_HISTORYENTRY_CONTRACTID, &kNS_HISTORYENTRY_CID },

View File

@ -361,11 +361,23 @@ class GeckoAppShell
gRestartScheduled = true;
}
static String[] getHandlersForMimeType(String aMimeType) {
static String[] getHandlersForMimeType(String aMimeType, String aAction) {
Intent intent = getIntentForActionString(aAction);
if (aMimeType != null && aMimeType.length() > 0)
intent.setType(aMimeType);
return getHandlersForIntent(intent);
}
static String[] getHandlersForProtocol(String aScheme, String aAction) {
Intent intent = getIntentForActionString(aAction);
Uri uri = new Uri.Builder().scheme(aScheme).build();
intent.setData(uri);
return getHandlersForIntent(intent);
}
static String[] getHandlersForIntent(Intent intent) {
PackageManager pm =
GeckoApp.surfaceView.getContext().getPackageManager();
Intent intent = new Intent();
intent.setType(aMimeType);
List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
int numAttr = 4;
String[] ret = new String[list.size() * numAttr];
@ -378,46 +390,34 @@ class GeckoAppShell
ret[i * numAttr + 1] = "";
ret[i * numAttr + 2] = resolveInfo.activityInfo.applicationInfo.packageName;
ret[i * numAttr + 3] = resolveInfo.activityInfo.name;
}
return ret;
}
static String[] getHandlersForProtocol(String aScheme) {
PackageManager pm =
GeckoApp.surfaceView.getContext().getPackageManager();
Intent intent = new Intent();
Uri uri = new Uri.Builder().scheme(aScheme).build();
intent.setData(uri);
List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
int numAttr = 4;
String[] ret = new String[list.size() * numAttr];
for (int i = 0; i < list.size(); i++) {
ResolveInfo resolveInfo = list.get(i);
ret[i * numAttr] = resolveInfo.loadLabel(pm).toString();
if (resolveInfo.isDefault)
ret[i * numAttr + 1] = "default";
else
ret[i * numAttr + 1] = "";
ret[i * numAttr + 2] = resolveInfo.activityInfo.applicationInfo.packageName;
ret[i * numAttr + 3] = resolveInfo.activityInfo.name;
}
return ret;
static Intent getIntentForActionString(String aAction) {
// Default to the view action if no other action as been specified.
if (aAction != null && aAction.length() > 0)
return new Intent(aAction);
else
return new Intent(Intent.ACTION_VIEW);
}
static String getMimeTypeFromExtension(String aFileExt) {
return android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(aFileExt);
}
static boolean openUriExternal(String aUriSpec, String aMimeType,
String aPackageName, String aClassName) {
// XXX: It's not clear if we should set the action to view or leave it open
Intent intent = new Intent(Intent.ACTION_VIEW);
if (aMimeType.length() > 0)
static boolean openUriExternal(String aUriSpec, String aMimeType, String aPackageName,
String aClassName, String aAction) {
Intent intent = getIntentForActionString(aAction);
if (aAction.equalsIgnoreCase(Intent.ACTION_SEND)) {
intent.putExtra(Intent.EXTRA_TEXT, aUriSpec);
if (aMimeType != null && aMimeType.length() > 0)
intent.setType(aMimeType);
} else if (aMimeType.length() > 0) {
intent.setDataAndType(Uri.parse(aUriSpec), aMimeType);
else
} else {
intent.setData(Uri.parse(aUriSpec));
}
if (aPackageName.length() > 0 && aClassName.length() > 0)
intent.setClassName(aPackageName, aClassName);

View File

@ -106,6 +106,8 @@ endif
ifeq ($(MOZ_WIDGET_TOOLKIT),android)
OSHELPER += nsMIMEInfoAndroid.cpp
OSHELPER += nsAndroidHandlerApp.cpp
OSHELPER += nsExternalSharingAppService.cpp
EXPORTS += nsExternalSharingAppService.h
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),qt)
@ -132,8 +134,9 @@ EXPORTS_mozilla/dom = \
ExternalHelperAppParent.h \
ExternalHelperAppChild.h
EXPORTS = \
EXPORTS += \
$(OSDIR)/nsOSHelperAppService.h \
nsExternalHelperAppService.h \
$(NULL)
XPIDLSRCS = \
@ -143,6 +146,7 @@ XPIDLSRCS = \
nsIHelperAppLauncherDialog.idl \
nsIContentDispatchChooser.idl \
nsIHandlerService.idl \
nsIExternalSharingAppService.idl \
$(NULL)
CPPSRCS = \

View File

@ -39,16 +39,17 @@
#include "AndroidBridge.h"
NS_IMPL_ISUPPORTS1(nsAndroidHandlerApp, nsIHandlerApp)
NS_IMPL_ISUPPORTS1(nsAndroidHandlerApp, nsISharingHandlerApp)
nsAndroidHandlerApp::nsAndroidHandlerApp(const nsAString& aName,
const nsAString& aDescription,
const nsAString& aPackageName,
const nsAString& aClassName,
const nsACString& aMimeType) :
const nsACString& aMimeType,
const nsAString& aAction) :
mName(aName), mDescription(aDescription), mPackageName(aPackageName),
mClassName(aClassName), mMimeType(aMimeType)
mClassName(aClassName), mMimeType(aMimeType), mAction(aAction)
{
}
@ -56,32 +57,37 @@ nsAndroidHandlerApp::~nsAndroidHandlerApp()
{
}
nsresult nsAndroidHandlerApp::GetName(nsAString & aName)
NS_IMETHODIMP
nsAndroidHandlerApp::GetName(nsAString & aName)
{
aName.Assign(mName);
return NS_OK;
}
nsresult nsAndroidHandlerApp::SetName(const nsAString & aName)
NS_IMETHODIMP
nsAndroidHandlerApp::SetName(const nsAString & aName)
{
mName.Assign(aName);
return NS_OK;
}
nsresult nsAndroidHandlerApp::GetDetailedDescription(nsAString & aDescription)
NS_IMETHODIMP
nsAndroidHandlerApp::GetDetailedDescription(nsAString & aDescription)
{
aDescription.Assign(mDescription);
return NS_OK;
}
nsresult nsAndroidHandlerApp::SetDetailedDescription(const nsAString & aDescription)
NS_IMETHODIMP
nsAndroidHandlerApp::SetDetailedDescription(const nsAString & aDescription)
{
mDescription.Assign(aDescription);
return NS_OK;
}
nsresult nsAndroidHandlerApp::Equals(nsIHandlerApp *aHandlerApp, PRBool *aRetval)
NS_IMETHODIMP
nsAndroidHandlerApp::Equals(nsIHandlerApp *aHandlerApp, PRBool *aRetval)
{
nsCOMPtr<nsAndroidHandlerApp> aApp = do_QueryInterface(aHandlerApp);
*aRetval = aApp && aApp->mName.Equals(mName) &&
@ -89,7 +95,8 @@ nsresult nsAndroidHandlerApp::Equals(nsIHandlerApp *aHandlerApp, PRBool *aRetval
return NS_OK;
}
nsresult nsAndroidHandlerApp::LaunchWithURI(nsIURI *aURI, nsIInterfaceRequestor *aWindowContext)
NS_IMETHODIMP
nsAndroidHandlerApp::LaunchWithURI(nsIURI *aURI, nsIInterfaceRequestor *aWindowContext)
{
if (!mozilla::AndroidBridge::Bridge())
return NS_ERROR_FAILURE;
@ -97,7 +104,18 @@ nsresult nsAndroidHandlerApp::LaunchWithURI(nsIURI *aURI, nsIInterfaceRequestor
nsCString uriSpec;
aURI->GetSpec(uriSpec);
return mozilla::AndroidBridge::Bridge()->
OpenUriExternal(uriSpec, mMimeType, mPackageName, mClassName) ?
OpenUriExternal(uriSpec, mMimeType, mPackageName, mClassName, mAction) ?
NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsAndroidHandlerApp::Share(const nsAString & data, const nsAString & title)
{
if (!mozilla::AndroidBridge::Bridge())
return NS_ERROR_FAILURE;
return mozilla::AndroidBridge::Bridge()->
OpenUriExternal(NS_ConvertUTF16toUTF8(data), mMimeType, mPackageName,
mClassName, mAction) ? NS_OK : NS_ERROR_FAILURE;
}

View File

@ -39,15 +39,19 @@
#define nsAndroidHandlerApp_h
#include "nsMIMEInfoImpl.h"
#include "nsIExternalSharingAppService.h"
class nsAndroidHandlerApp : public nsIHandlerApp {
class nsAndroidHandlerApp : public nsISharingHandlerApp {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIHANDLERAPP
NS_DECL_NSISHARINGHANDLERAPP
public:
nsAndroidHandlerApp(const nsAString& aName, const nsAString& aDescription,
const nsAString& aPackageName, const nsAString& aClassName,
const nsACString& aMimeType);
const nsAString& aPackageName,
const nsAString& aClassName,
const nsACString& aMimeType, const nsAString& aAction);
virtual ~nsAndroidHandlerApp();
private:
@ -56,5 +60,6 @@ private:
nsCString mMimeType;
nsString mClassName;
nsString mPackageName;
nsString mAction;
};
#endif

View File

@ -0,0 +1,99 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla browser.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
*
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brad Lassey <blassey@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#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_ISUPPORTS1(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();
if (AndroidBridge::Bridge())
return AndroidBridge::Bridge()->
OpenUriExternal(NS_ConvertUTF16toUTF8(data), NS_ConvertUTF16toUTF8(mime),
emptyString,emptyString, sendAction) ? NS_OK : NS_ERROR_FAILURE;
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsExternalSharingAppService::GetSharingApps(const nsAString & aMIMEType,
PRUint32 *aLen NS_OUTPARAM,
nsISharingHandlerApp ***aHandlers NS_OUTPARAM)
{
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);
NS_ConvertUTF16toUTF8 nMimeType(aMIMEType);
if (!AndroidBridge::Bridge())
return NS_OK;
AndroidBridge::Bridge()->GetHandlersForMimeType(nMimeType.get(), array,
nsnull, sendAction);
array->GetLength(aLen);
*aHandlers =
static_cast<nsISharingHandlerApp**>(NS_Alloc(sizeof(nsISharingHandlerApp*)
* *aLen));
for (int i = 0; i < *aLen; i++) {
rv = array->QueryElementAt(i, nsISharingHandlerApp::GetIID(),
(void**)(*aHandlers + i));
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}

View File

@ -0,0 +1,60 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla browser.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
*
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brad Lassey <blassey@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#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 : public nsIExternalSharingAppService
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIEXTERNALSHARINGAPPSERVICE
nsExternalSharingAppService();
private:
~nsExternalSharingAppService();
};
#endif /*NS_EXTERNAL_SHARING_APP_SERVICE_H */

View File

@ -76,24 +76,20 @@ nsMIMEInfoAndroid::GetMimeInfoForMimeType(const nsACString& aMimeType,
info.forget(aMimeInfo);
return PR_TRUE;
}
nsStringArray stringArray;
bridge->GetHandlersForMimeType(nsCAutoString(aMimeType).get(), &stringArray);
nsString empty = EmptyString();
PRInt32 len = stringArray.Count();
if (len == 0) {
nsIHandlerApp* systemDefault = nsnull;
bridge->GetHandlersForMimeType(nsCAutoString(aMimeType).get(),
info->mHandlerApps, &systemDefault);
if (systemDefault)
info->mPrefApp = systemDefault;
PRUint32 len;
info->mHandlerApps->GetLength(&len);
if (len == 1) {
info.forget(aMimeInfo);
return PR_FALSE;
}
for (jsize i = 0; i < len; i+=4) {
nsAndroidHandlerApp* app =
new nsAndroidHandlerApp(*stringArray[i], empty, *stringArray[i + 2],
*stringArray[i + 3], aMimeType);
info->mHandlerApps->AppendElement(app, PR_FALSE);
if (stringArray[i + 1] > 0)
info->mPrefApp = app;
}
info.forget(aMimeInfo);
return PR_TRUE;
@ -115,7 +111,6 @@ nsMIMEInfoAndroid::GetMimeInfoForProtocol(const nsACString &aScheme,
PRBool *found,
nsIHandlerInfo **info)
{
const nsString &empty = EmptyString();
const nsCString &emptyC = EmptyCString();
mozilla::AndroidBridge* bridge = mozilla::AndroidBridge::Bridge();
nsMIMEInfoAndroid *mimeinfo = new nsMIMEInfoAndroid(emptyC);
@ -128,26 +123,23 @@ nsMIMEInfoAndroid::GetMimeInfoForProtocol(const nsACString &aScheme,
return NS_OK;
}
nsIHandlerApp* systemDefault = nsnull;
bridge->GetHandlersForProtocol(nsCAutoString(aScheme).get(),
mimeinfo->mHandlerApps, &systemDefault);
if (systemDefault)
mimeinfo->mPrefApp = systemDefault;
nsStringArray stringArray;
bridge->GetHandlersForProtocol(nsCAutoString(aScheme).get(), &stringArray);
PRInt32 len = stringArray.Count();
if (len == 0) {
PRUint32 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 = PR_FALSE;
return NS_OK;
}
for (jsize i = 0; i < len; i+=4) {
nsAndroidHandlerApp* app =
new nsAndroidHandlerApp(*stringArray[i], empty, *stringArray[i + 2],
*stringArray[i + 3], emptyC);
mimeinfo->mHandlerApps->AppendElement(app, PR_FALSE);
if (!stringArray[i + 1]->IsEmpty())
mimeinfo->mPrefApp = app;
}
return NS_OK;
}

View File

@ -86,3 +86,14 @@ nsresult nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const nsACString &aS
return nsMIMEInfoAndroid::GetMimeInfoForProtocol(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);
}

View File

@ -60,7 +60,13 @@ public:
PRBool *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 */

View File

@ -43,6 +43,7 @@
#include "nsExternalHelperAppService.h"
#include "nsCExternalHandlerService.h"
#include "nsMIMEInfoImpl.h"
#include "nsCOMPtr.h"
class nsMIMEInfoBeOS;

View File

@ -48,6 +48,7 @@
#include "nsExternalHelperAppService.h"
#include "nsCExternalHandlerService.h"
#include "nsMIMEInfoImpl.h"
#include "nsCOMPtr.h"
class nsOSHelperAppService : public nsExternalHelperAppService

View File

@ -148,6 +148,10 @@
#include "ExternalHelperAppChild.h"
#endif
#ifdef ANDROID
#include "AndroidBridge.h"
#endif
// Buffer file writes in 32kb chunks
#define BUFFERED_OUTPUT_SIZE (1024 * 32)

View File

@ -57,7 +57,6 @@
#include "nsIHelperAppLauncherDialog.h"
#include "nsIMIMEInfo.h"
#include "nsMIMEInfoImpl.h"
#include "nsIMIMEService.h"
#include "nsIStreamListener.h"
#include "nsIFile.h"

View File

@ -0,0 +1,62 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla browser.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
*
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brad Lassey <blassey@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIMIMEInfo.idl"
%{C++
#define NS_EXTERNALSHARINGAPPSERVICE_CONTRACTID "@mozilla.org/uriloader/external-sharing-app-service;1"
#define NS_IEXTERNALSHARINGAPPSERVICE_CLASSNAME "Mozilla Sharing App Service"
%}
[scriptable, uuid(7111f769-53ec-41fd-b314-613661d5b6ba)]
interface nsISharingHandlerApp : nsIHandlerApp
{
void share(in AString data, [optional] in AString title);
};
[scriptable, uuid(cf7d04e5-3892-482e-81bb-073dc1c83f76)]
interface nsIExternalSharingAppService : nsISupports {
void shareWithDefault(in AString data, in AString mime,
[optional] in AString title);
void getSharingApps(in AString aMIMEType,
[optional] out unsigned long aLen,
[array, size_is(aLen), retval] out nsISharingHandlerApp handlerApps);
};

View File

@ -47,6 +47,7 @@
#include "nsExternalHelperAppService.h"
#include "nsCExternalHandlerService.h"
#include "nsMIMEInfoImpl.h"
#include "nsCOMPtr.h"
#define LOG(args) PR_LOG(mLog, PR_LOG_DEBUG, args)

View File

@ -47,6 +47,7 @@
#include "nsExternalHelperAppService.h"
#include "nsCExternalHandlerService.h"
#include "nsMIMEInfoImpl.h"
#include "nsCOMPtr.h"
class nsHashtable;

View File

@ -45,6 +45,7 @@
#include "nsExternalHelperAppService.h"
#include "nsCExternalHandlerService.h"
#include "nsMIMEInfoImpl.h"
#include "nsCOMPtr.h"
#include <windows.h>

View File

@ -46,6 +46,7 @@
#include "AndroidBridge.h"
#include "nsAppShell.h"
#include "nsOSHelperAppService.h"
using namespace mozilla;
@ -103,9 +104,9 @@ AndroidBridge::Init(JNIEnv *jEnv,
jReturnIMEQueryResult = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "returnIMEQueryResult", "(Ljava/lang/String;II)V");
jScheduleRestart = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "scheduleRestart", "()V");
jNotifyXreExit = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "onXreExit", "()V");
jGetHandlersForMimeType = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getHandlersForMimeType", "(Ljava/lang/String;)[Ljava/lang/String;");
jGetHandlersForProtocol = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getHandlersForProtocol", "(Ljava/lang/String;)[Ljava/lang/String;");
jOpenUriExternal = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "openUriExternal", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z");
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;)Z");
jGetMimeTypeFromExtension = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getMimeTypeFromExtension", "(Ljava/lang/String;)Ljava/lang/String;");
jMoveTaskToBack = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "moveTaskToBack", "()V");
jGetClipboardText = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getClipboardText", "()Ljava/lang/String;");
@ -258,65 +259,99 @@ AndroidBridge::NotifyXreExit()
mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jNotifyXreExit);
}
PRBool
AndroidBridge::GetHandlersForMimeType(const char *aMimeType, nsStringArray* aStringArray)
static void
getHandlersFromStringArray(JNIEnv *aJNIEnv, jobjectArray jArr, jsize aLen,
nsIMutableArray *aHandlersArray,
nsIHandlerApp **aDefaultApp,
const nsAString& aAction = EmptyString(),
const nsACString& aMimeType = EmptyCString())
{
nsString empty = EmptyString();
for (jsize i = 0; i < aLen; i+=4) {
nsJNIString name(
static_cast<jstring>(aJNIEnv->GetObjectArrayElement(jArr, i)));
nsJNIString isDefault(
static_cast<jstring>(aJNIEnv->GetObjectArrayElement(jArr, i + 1)));
nsJNIString packageName(
static_cast<jstring>(aJNIEnv->GetObjectArrayElement(jArr, i + 2)));
nsJNIString className(
static_cast<jstring>(aJNIEnv->GetObjectArrayElement(jArr, i + 3)));
nsIHandlerApp* app = nsOSHelperAppService::
CreateAndroidHandlerApp(name, className, packageName,
className, aMimeType, aAction);
aHandlersArray->AppendElement(app, PR_FALSE);
if (aDefaultApp && isDefault.Length() > 0)
*aDefaultApp = app;
}
}
PRBool
AndroidBridge::GetHandlersForMimeType(const char *aMimeType,
nsIMutableArray *aHandlersArray,
nsIHandlerApp **aDefaultApp,
const nsAString& aAction)
{
NS_PRECONDITION(aStringArray != nsnull, "null array pointer passed in");
AutoLocalJNIFrame jniFrame;
NS_ConvertUTF8toUTF16 wMimeType(aMimeType);
jstring jstr = mJNIEnv->NewString(wMimeType.get(), wMimeType.Length());
jstring jstrMimeType =
mJNIEnv->NewString(wMimeType.get(), wMimeType.Length());
const PRUnichar* wAction;
PRUint32 actionLen = NS_StringGetData(aAction, &wAction);
jstring jstrAction = mJNIEnv->NewString(wAction, actionLen);
jobject obj = mJNIEnv->CallStaticObjectMethod(mGeckoAppShellClass,
jGetHandlersForMimeType,
jstr);
jstrMimeType, jstrAction);
jobjectArray arr = static_cast<jobjectArray>(obj);
if (!arr)
return PR_FALSE;
jsize len = mJNIEnv->GetArrayLength(arr);
if (!aStringArray)
if (!aHandlersArray)
return len > 0;
for (jsize i = 0; i < len; i++) {
jstring jstr = static_cast<jstring>(mJNIEnv->GetObjectArrayElement(arr, i));
nsJNIString jniStr(jstr);
aStringArray->InsertStringAt(jniStr, i);
}
getHandlersFromStringArray(mJNIEnv, arr, len, aHandlersArray,
aDefaultApp, aAction,
nsDependentCString(aMimeType));
return PR_TRUE;
}
PRBool
AndroidBridge::GetHandlersForProtocol(const char *aScheme, nsStringArray* aStringArray)
AndroidBridge::GetHandlersForProtocol(const char *aScheme,
nsIMutableArray* aHandlersArray,
nsIHandlerApp **aDefaultApp,
const nsAString& aAction)
{
NS_PRECONDITION(aStringArray != nsnull, "null array pointer passed in");
AutoLocalJNIFrame jniFrame;
NS_ConvertUTF8toUTF16 wScheme(aScheme);
jstring jstr = mJNIEnv->NewString(wScheme.get(), wScheme.Length());
jstring jstrScheme = mJNIEnv->NewString(wScheme.get(), wScheme.Length());
const PRUnichar* wAction;
PRUint32 actionLen = NS_StringGetData(aAction, &wAction);
jstring jstrAction = mJNIEnv->NewString(wAction, actionLen);
jobject obj = mJNIEnv->CallStaticObjectMethod(mGeckoAppShellClass,
jGetHandlersForProtocol,
jstr);
jstrScheme, jstrAction);
jobjectArray arr = static_cast<jobjectArray>(obj);
if (!arr)
return PR_FALSE;
jsize len = mJNIEnv->GetArrayLength(arr);
if (!aStringArray)
if (!aHandlersArray)
return len > 0;
for (jsize i = 0; i < len; i++) {
jstring jstr = static_cast<jstring>(mJNIEnv->GetObjectArrayElement(arr, i));
nsJNIString jniStr(jstr);
aStringArray->InsertStringAt(jniStr, i);
}
getHandlersFromStringArray(mJNIEnv, arr, len, aHandlersArray,
aDefaultApp, aAction);
return PR_TRUE;
}
PRBool
AndroidBridge::OpenUriExternal(const nsACString& aUriSpec, const nsACString& aMimeType,
const nsAString& aPackageName, const nsAString& aClassName)
const nsAString& aPackageName, const nsAString& aClassName,
const nsAString& aAction)
{
AutoLocalJNIFrame jniFrame;
NS_ConvertUTF8toUTF16 wUriSpec(aUriSpec);
@ -325,14 +360,19 @@ AndroidBridge::OpenUriExternal(const nsACString& aUriSpec, const nsACString& aMi
PRUint32 packageNameLen = NS_StringGetData(aPackageName, &wPackageName);
const PRUnichar* wClassName;
PRUint32 classNameLen = NS_StringGetData(aClassName, &wClassName);
const PRUnichar* wAction;
PRUint32 actionLen = NS_StringGetData(aAction, &wAction);
jstring jstrUri = mJNIEnv->NewString(wUriSpec.get(), wUriSpec.Length());
jstring jstrType = mJNIEnv->NewString(wMimeType.get(), wMimeType.Length());
jstring jstrPackage = mJNIEnv->NewString(wPackageName, packageNameLen);
jstring jstrClass = mJNIEnv->NewString(wClassName, classNameLen);
jstring jstrAction = mJNIEnv->NewString(wAction, actionLen);
return mJNIEnv->CallStaticBooleanMethod(mGeckoAppShellClass,
jOpenUriExternal,
jstrUri, jstrType, jstrPackage, jstrClass);
jstrUri, jstrType, jstrPackage,
jstrClass, jstrAction);
}
void

View File

@ -47,7 +47,8 @@
#include "AndroidJavaWrappers.h"
#include "nsVoidArray.h"
#include "nsIMutableArray.h"
#include "nsIMIMEInfo.h"
// Some debug #defines
// #define ANDROID_DEBUG_EVENTS
@ -117,13 +118,20 @@ public:
void SetSurfaceView(jobject jobj);
AndroidGeckoSurfaceView& SurfaceView() { return mSurfaceView; }
PRBool GetHandlersForProtocol(const char *aScheme, nsStringArray* aStringArray = nsnull);
PRBool GetHandlersForProtocol(const char *aScheme,
nsIMutableArray* handlersArray = nsnull,
nsIHandlerApp **aDefaultApp = nsnull,
const nsAString& aAction = EmptyString());
PRBool GetHandlersForMimeType(const char *aMimeType, nsStringArray* aStringArray = nsnull);
PRBool GetHandlersForMimeType(const char *aMimeType,
nsIMutableArray* handlersArray = nsnull,
nsIHandlerApp **aDefaultApp = nsnull,
const nsAString& aAction = EmptyString());
PRBool OpenUriExternal(const nsACString& aUriSpec, const nsACString& aMimeType,
const nsAString& aPackageName = EmptyString(),
const nsAString& aClassName = EmptyString());
const nsAString& aClassName = EmptyString(),
const nsAString& aAction = EmptyString());
void GetMimeTypeFromExtension(const nsACString& aFileExt, nsCString& aMimeType);