bug 565138 - Implement extloader backend for Android r=vlad

This commit is contained in:
Brad Lassey 2010-06-14 15:04:16 -04:00
parent a8a12a8bb0
commit 4346c1fc9c
16 changed files with 900 additions and 4 deletions

View File

@ -76,6 +76,18 @@ abstract public class GeckoApp
env = i.getStringExtra("env" + c);
Log.i("GeckoApp", "env"+ c +": "+ env);
}
String tmpdir = System.getProperty("java.io.tmpdir");
if (tmpdir == null) {
try {
File f = Environment.getDownloadCacheDirectory();
dalvik.system.TemporaryDirectory.setUpDirectory(f);
tmpdir = f.getPath();
} catch (Exception e) {
Log.e("GeckoApp", "error setting up tmp dir" + e);
}
}
GeckoAppShell.putenv("TMPDIR=" + tmpdir);
GeckoAppShell.runGecko(getApplication().getPackageResourcePath(),
i.getStringExtra("args"),
i.getDataString());

View File

@ -1,4 +1,4 @@
/* -*- Mode: Java; tab-width: 20; indent-tabs-mode: nil; -*-
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -55,6 +55,9 @@ import android.location.*;
import android.util.*;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
class GeckoAppShell
{
@ -235,4 +238,39 @@ class GeckoAppShell
Log.i("GeckoAppJava", "scheduling restart");
gRestartScheduled = true;
}
static String[] getHandlersForMimeType(String aMimeType) {
PackageManager pm =
GeckoApp.surfaceView.getContext().getPackageManager();
Intent intent = new Intent();
intent.setType(aMimeType);
List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
int numAttr = 2;
String[] ret = new String[list.size() * numAttr];
for (int i = 0; i < list.size(); i++) {
ret[i * numAttr] = list.get(i).loadLabel(pm).toString();
if (list.get(i).isDefault)
ret[i * numAttr + 1] = "default";
else
ret[i * numAttr + 1] = "";
}
return ret;
}
static String getMimeTypeFromExtension(String aFileExt) {
return android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(aFileExt);
}
static boolean openUriExternal(String aUriSpec, String aMimeType) {
// XXX: It's not clear if we should set the action to view or leave it open
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(android.net.Uri.parse(aUriSpec), aMimeType);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
GeckoApp.surfaceView.getContext().startActivity(intent);
return true;
} catch(ActivityNotFoundException e) {
return false;
}
}
}

View File

@ -1181,6 +1181,20 @@ nsDownloadManager::GetDefaultDownloadsDirectory(nsILocalFile **aResult)
rv = dirService->Get(NS_UNIX_XDG_DOCUMENTS_DIR,
NS_GET_IID(nsILocalFile),
getter_AddRefs(downloadDir));
#elif defined(ANDROID)
// Android doesn't have a $HOME directory, and by default we only have
// write access to /data/data/org.mozilla.{$APP} and /sdcard
char* sdcard = getenv("EXTERNAL_STORAGE");
if (sdcard) {
rv = NS_NewNativeLocalFile(nsDependentCString(sdcard),
PR_TRUE, getter_AddRefs(downloadDir));
NS_ENSURE_SUCCESS(rv, rv);
rv = downloadDir->Append(NS_LITERAL_STRING("download"));
NS_ENSURE_SUCCESS(rv, rv);
}
else {
rv = NS_ERROR_FAILURE;
}
#else
rv = dirService->Get(NS_UNIX_DEFAULT_DOWNLOAD_DIR,
NS_GET_IID(nsILocalFile),

View File

@ -109,8 +109,6 @@ GeckoStart(void *data)
appData->xreDirectory = xreDir.get();
// SpecialSystemDirectory.cpp sets its TMPDIR from this env var
setenv("TMPDIR", "/data/data/org.mozilla." MOZ_APP_NAME, 1);
nsTArray<char *> targs;
char *arg = strtok(static_cast<char *>(data), " ");

View File

@ -60,11 +60,15 @@ else
ifeq ($(MOZ_WIDGET_TOOLKIT),beos)
OSDIR = beos
else
ifeq ($(MOZ_WIDGET_TOOLKIT),android)
OSDIR = android
else
OSDIR = unix
endif
endif
endif
endif
endif
VPATH := $(srcdir) $(srcdir)/$(OSDIR)
@ -90,6 +94,11 @@ OSHELPER += nsGNOMERegistry.cpp
OSHELPER += nsMIMEInfoUnix.cpp
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),android)
OSHELPER += nsMIMEInfoAndroid.cpp
OSHELPER += nsAndroidHandlerApp.cpp
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),qt)
OSHELPER += nsGNOMERegistry.cpp
OSHELPER += nsMIMEInfoUnix.cpp

View File

@ -0,0 +1,91 @@
/* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** 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 Android code.
*
* 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 "nsAndroidHandlerApp.h"
NS_IMPL_ISUPPORTS1(nsAndroidHandlerApp, nsIHandlerApp)
nsAndroidHandlerApp::nsAndroidHandlerApp(nsAString& aName,
nsAString& aDescription) :
mName(aName), mDescription(aDescription)
{
}
nsAndroidHandlerApp::~nsAndroidHandlerApp()
{
}
nsresult nsAndroidHandlerApp::GetName(nsAString & aName)
{
aName.Assign(mName);
return NS_OK;
}
nsresult nsAndroidHandlerApp::SetName(const nsAString & aName)
{
mName.Assign(aName);
return NS_OK;
}
nsresult nsAndroidHandlerApp::GetDetailedDescription(nsAString & aDescription)
{
aDescription.Assign(mDescription);
return NS_OK;
}
nsresult nsAndroidHandlerApp::SetDetailedDescription(const nsAString & aDescription)
{
mDescription.Assign(aDescription);
return NS_OK;
}
nsresult nsAndroidHandlerApp::Equals(nsIHandlerApp *aHandlerApp, PRBool *aRetval)
{
nsCOMPtr<nsAndroidHandlerApp> aApp = do_QueryInterface(aHandlerApp);
*aRetval = aApp && aApp->mName.Equals(mName) &&
aApp->mDescription.Equals(mDescription);
return NS_OK;
}
nsresult nsAndroidHandlerApp::LaunchWithURI(nsIURI *aURI, nsIInterfaceRequestor *aWindowContext)
{
nsCAutoString uristr;
aURI->GetAsciiSpec(uristr);
return NS_OK;
}

View File

@ -0,0 +1,56 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** 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 Android code.
*
* 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 nsAndroidHandlerApp_h
#define nsAndroidHandlerApp_h
#include "nsMIMEInfoImpl.h"
class nsAndroidHandlerApp : public nsIHandlerApp {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIHANDLERAPP
public:
nsAndroidHandlerApp(nsAString& aName, nsAString& aDescription);
virtual ~nsAndroidHandlerApp();
private:
nsString mName;
nsString mDescription;
};
#endif

View File

@ -0,0 +1,378 @@
/* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** 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 Android code.
*
* 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):
* Michael Wu <mwu@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 "nsMIMEInfoAndroid.h"
#include "AndroidBridge.h"
#include "nsAndroidHandlerApp.h"
#include "nsArrayUtils.h"
#include "nsISupportsUtils.h"
#include "nsStringEnumerator.h"
#include "nsNetUtil.h"
NS_IMPL_ISUPPORTS1(nsMIMEInfoAndroid, nsIMIMEInfo)
nsMIMEInfoAndroid::~nsMIMEInfoAndroid()
{
}
NS_IMETHODIMP
nsMIMEInfoAndroid::LaunchDefaultWithFile(nsIFile* aFile)
{
LaunchWithFile(aFile);
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoAndroid::LoadUriInternal(nsIURI * aURI)
{
nsCString uriSpec;
aURI->GetSpec(uriSpec);
return mozilla::AndroidBridge::Bridge()->
OpenUriExternal(uriSpec, mMimeType) ? NS_OK : NS_ERROR_FAILURE;
}
already_AddRefed<nsIMIMEInfo>
nsMIMEInfoAndroid::GetMimeInfoForMimeType(const nsACString& aMimeType)
{
mozilla::AndroidBridge* bridge = mozilla::AndroidBridge::Bridge();
nsStringArray stringArray;
bridge->GetHandlersForMimeType(nsCAutoString(aMimeType).get(), &stringArray);
nsString empty = EmptyString();
PRInt32 len = stringArray.Count();
if (len == 0)
return nsnull;
nsCOMPtr<nsMIMEInfoAndroid> info = new nsMIMEInfoAndroid(aMimeType);
for (jsize i = 0; i < len; i+=2) {
nsAndroidHandlerApp* app = new nsAndroidHandlerApp(*stringArray[i], empty);
info->mHandlerApps->AppendElement(app, PR_FALSE);
if (stringArray[i + 1] > 0)
info->mPrefApp = app;
}
nsCOMPtr<nsIMIMEInfo> ret = do_QueryInterface(info);
return ret.forget();
}
already_AddRefed<nsIMIMEInfo>
nsMIMEInfoAndroid::GetMimeInfoForFileExt(const nsACString& aFileExt)
{
nsCString mimeType;
mozilla::AndroidBridge::Bridge()->GetMimeTypeFromExtension(nsCString(aFileExt), mimeType);
return GetMimeInfoForMimeType(mimeType);
}
NS_IMETHODIMP
nsMIMEInfoAndroid::GetType(nsACString& aType)
{
aType.Assign(mMimeType);
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;
if (*aApp) {
nsAutoString appName;
(*aApp)->GetName(appName);
}
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(PRBool* aHasDefault)
{
PRUint32 len;
*aHasDefault = PR_FALSE;
if (!mHandlerApps)
return NS_OK;
if (NS_FAILED(mHandlerApps->GetLength(&len)))
return NS_OK;
if (len == 0)
return NS_OK;
*aHasDefault = PR_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(PRBool* aAlwaysAsk)
{
*aAlwaysAsk = mAlwaysAsk;
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoAndroid::SetAlwaysAskBeforeHandling(PRBool 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);
PRInt32 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, PRBool *aRetVal)
{
NS_ASSERTION(!aExtension.IsEmpty(), "no extension");
PRBool found = PR_FALSE;
PRUint32 extCount = mExtensions.Length();
if (extCount < 1) return NS_OK;
for (PRUint8 i=0; i < extCount; i++) {
const nsCString& ext = mExtensions[i];
if (ext.Equals(aExtension, nsCaseInsensitiveCStringComparator())) {
found = PR_TRUE;
break;
}
}
*aRetVal = found;
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)
{
NS_ASSERTION(!aExtension.IsEmpty(), "no extension");
PRUint32 extCount = mExtensions.Length();
PRUint8 i;
PRBool found = PR_FALSE;
for (i=0; i < extCount; i++) {
const nsCString& ext = mExtensions[i];
if (ext.Equals(aExtension, nsCaseInsensitiveCStringComparator())) {
found = PR_TRUE;
break;
}
}
if (found) {
mExtensions.RemoveElementAt(i);
}
mExtensions.InsertElementAt(0, aExtension);
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoAndroid::GetMIMEType(nsACString & aMIMEType)
{
aMIMEType.Assign(mMimeType);
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoAndroid::Equals(nsIMIMEInfo *aMIMEInfo, PRBool *aRetVal)
{
if (!aMIMEInfo) return NS_ERROR_NULL_POINTER;
nsCAutoString type;
nsresult rv = aMIMEInfo->GetMIMEType(type);
if (NS_FAILED(rv)) return rv;
*aRetVal = mMimeType.Equals(type);
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoAndroid::GetPossibleLocalHandlers(nsIArray * *aPossibleLocalHandlers)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMIMEInfoAndroid::LaunchWithFile(nsIFile *aFile)
{
nsIURI* uri;
NS_NewFileURI(&uri, aFile);
LoadUriInternal(uri);
return NS_OK;
}
nsMIMEInfoAndroid::nsMIMEInfoAndroid(const nsACString& aMIMEType) :
mMimeType(aMIMEType), mAlwaysAsk(PR_TRUE),
mPrefAction(nsIMIMEInfo::useHelperApp),
mSystemChooser(this)
{
mPrefApp = &mSystemChooser;
nsresult rv;
mHandlerApps = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
mHandlerApps->AppendElement(mPrefApp, PR_FALSE);
}
NS_IMPL_ISUPPORTS1(nsMIMEInfoAndroid::SystemChooser, nsIHandlerApp)
nsresult nsMIMEInfoAndroid::SystemChooser::GetName(nsAString & aName) {
aName.Assign(NS_LITERAL_STRING("Android chooser"));
return NS_OK;
}
nsresult
nsMIMEInfoAndroid::SystemChooser::SetName(const nsAString&) {
return NS_OK;
}
nsresult
nsMIMEInfoAndroid::SystemChooser::GetDetailedDescription(nsAString & aDesc) {
aDesc.Assign(NS_LITERAL_STRING("Android's default handler application chooser"));
return NS_OK;
}
nsresult
nsMIMEInfoAndroid::SystemChooser::SetDetailedDescription(const nsAString&) {
return NS_OK;
}
nsresult
nsMIMEInfoAndroid::SystemChooser::Equals(nsIHandlerApp *aHandlerApp, PRBool *aRetVal) {
nsCOMPtr<nsMIMEInfoAndroid::SystemChooser> info = do_QueryInterface(aHandlerApp);
if (info)
return mOuter->Equals(info->mOuter, aRetVal);
*aRetVal = PR_FALSE;
return NS_OK;
}
nsresult
nsMIMEInfoAndroid::SystemChooser::LaunchWithURI(nsIURI* aURI, nsIInterfaceRequestor*)
{
return mOuter->LoadUriInternal(aURI);
}

View File

@ -0,0 +1,81 @@
/* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** 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 Android code.
*
* 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):
* Michael Wu <mwu@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 nsMIMEInfoAndroid_h
#define nsMIMEInfoAndroid_h
#include "nsMIMEInfoImpl.h"
#include "nsIMutableArray.h"
#include "nsAndroidHandlerApp.h"
class nsMIMEInfoAndroid : public nsIMIMEInfo
{
public:
static already_AddRefed<nsIMIMEInfo> GetMimeInfoForMimeType(const nsACString& aMimeType);
static already_AddRefed<nsIMIMEInfo> GetMimeInfoForFileExt(const nsACString& aFileExt);
NS_DECL_ISUPPORTS
NS_DECL_NSIMIMEINFO
NS_DECL_NSIHANDLERINFO
private:
nsMIMEInfoAndroid(const nsACString& aMIMEType);
virtual ~nsMIMEInfoAndroid();
protected:
virtual NS_HIDDEN_(nsresult) LaunchDefaultWithFile(nsIFile* aFile);
virtual NS_HIDDEN_(nsresult) LoadUriInternal(nsIURI *aURI);
nsCOMPtr<nsIMutableArray> mHandlerApps;
nsCString mMimeType;
nsTArray<nsCString> mExtensions;
PRBool mAlwaysAsk;
nsHandlerInfoAction mPrefAction;
nsString mDescription;
nsCOMPtr<nsIHandlerApp> mPrefApp;
class SystemChooser : public nsIHandlerApp {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIHANDLERAPP
SystemChooser(nsMIMEInfoAndroid* aOuter): mOuter(aOuter) {};
private:
nsMIMEInfoAndroid* mOuter;
};
SystemChooser mSystemChooser;
};
#endif /* nsMIMEInfoAndroid_h */

View File

@ -0,0 +1,71 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** 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 Android code.
*
* 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):
* Michael Wu <mwu@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 "nsOSHelperAppService.h"
#include "nsMIMEInfoAndroid.h"
nsOSHelperAppService::nsOSHelperAppService() : nsExternalHelperAppService()
{
}
nsOSHelperAppService::~nsOSHelperAppService()
{
}
already_AddRefed<nsIMIMEInfo>
nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt,
PRBool* aFound)
{
*aFound = PR_FALSE;
already_AddRefed<nsIMIMEInfo> mimeInfo =
nsMIMEInfoAndroid::GetMimeInfoForMimeType(aMIMEType);
if (!mimeInfo.get())
mimeInfo = nsMIMEInfoAndroid::GetMimeInfoForFileExt(aFileExt);
*aFound = !!mimeInfo.get();
return mimeInfo;
}
nsresult
nsOSHelperAppService::OSProtocolHandlerExists(const char* aScheme,
PRBool* aExists)
{
*aExists = PR_FALSE;
return NS_OK;
}

View File

@ -0,0 +1,60 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** 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 Android code.
*
* 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):
* Michael Wu <mwu@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 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,
PRBool* aFound);
virtual NS_HIDDEN_(nsresult)
OSProtocolHandlerExists(const char* aScheme,
PRBool* aExists);
};
#endif /* nsOSHelperAppService_h */

View File

@ -97,7 +97,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;");
jOpenUriExternal = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "openUriExternal", "(Ljava/lang/String;Ljava/lang/String;)Z");
jGetMimeTypeFromExtension = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getMimeTypeFromExtension", "(Ljava/lang/String;)Ljava/lang/String;");
InitAndroidJavaWrappers(jEnv);
// jEnv should NOT be cached here by anything -- the jEnv here
@ -212,6 +214,49 @@ AndroidBridge::NotifyXreExit()
mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jNotifyXreExit);
}
void
AndroidBridge::GetHandlersForMimeType(const char *aMimeType, nsStringArray* aStringArray)
{
AutoLocalJNIFrame jniFrame;
NS_ConvertUTF8toUTF16 wMimeType(aMimeType);
jstring jstr = mJNIEnv->NewString(wMimeType.get(), wMimeType.Length());
jobject obj = mJNIEnv->CallStaticObjectMethod(mGeckoAppShellClass,
jGetHandlersForMimeType,
jstr);
jobjectArray arr = static_cast<jobjectArray>(obj);
jsize len = mJNIEnv->GetArrayLength(arr);
for (jsize i = 0; i < len; i+=2) {
jstring jstr = static_cast<jstring>(mJNIEnv->GetObjectArrayElement(arr, i));
nsJNIString jniStr(jstr);
aStringArray->AppendString(jniStr);
}
}
PRBool
AndroidBridge::OpenUriExternal(nsCString& aUriSpec, nsCString& aMimeType)
{
AutoLocalJNIFrame jniFrame;
NS_ConvertUTF8toUTF16 wUriSpec(aUriSpec);
NS_ConvertUTF8toUTF16 wMimeType(aMimeType);
jstring jstrUri = mJNIEnv->NewString(wUriSpec.get(), wUriSpec.Length());
jstring jstrType = mJNIEnv->NewString(wMimeType.get(), wMimeType.Length());
return mJNIEnv->CallStaticBooleanMethod(mGeckoAppShellClass,
jOpenUriExternal,
jstrUri, jstrType);
}
void
AndroidBridge::GetMimeTypeFromExtension(const nsCString& aFileExt, nsCString& aMimeType) {
AutoLocalJNIFrame jniFrame;
NS_ConvertUTF8toUTF16 wFileExt(aFileExt);
jstring jstrExt = mJNIEnv->NewString(wFileExt.get(), wFileExt.Length());
jstring jstrType = static_cast<jstring>(mJNIEnv->CallStaticObjectMethod(mGeckoAppShellClass,
jGetMimeTypeFromExtension,
jstrExt));
nsJNIString jniStr(jstrType);
aMimeType.Assign(NS_ConvertUTF16toUTF8(jniStr.get()));
}
void
AndroidBridge::SetSurfaceView(jobject obj)
{

View File

@ -46,6 +46,8 @@
#include "AndroidJavaWrappers.h"
#include "nsVoidArray.h"
// Some debug #defines
// #define ANDROID_DEBUG_EVENTS
// #define ANDROID_DEBUG_WIDGET
@ -102,6 +104,12 @@ public:
void SetSurfaceView(jobject jobj);
AndroidGeckoSurfaceView& SurfaceView() { return mSurfaceView; }
void GetHandlersForMimeType(const char *aMimeType, nsStringArray* aStringArray);
PRBool OpenUriExternal(nsCString& aUriSpec, nsCString& aMimeType);
void GetMimeTypeFromExtension(const nsCString& aFileExt, nsCString& aMimeType);
struct AutoLocalJNIFrame {
AutoLocalJNIFrame(int nEntries = 128) : mEntries(nEntries) {
AndroidBridge::Bridge()->JNI()->PushLocalFrame(mEntries);
@ -148,6 +156,9 @@ protected:
jmethodID jNotifyXreExit;
jmethodID jScheduleRestart;
jmethodID jGetOutstandingDrawEvents;
jmethodID jGetHandlersForMimeType;
jmethodID jOpenUriExternal;
jmethodID jGetMimeTypeFromExtension;
};
}

View File

@ -408,3 +408,12 @@ AndroidRect::Init(JNIEnv *jenv, jobject jobj)
mBottom = 0;
}
}
nsJNIString::nsJNIString(jstring jstr)
{
const jchar* jCharPtr = JNI()->GetStringChars(jstr, false);
nsresult rv;
Assign(jCharPtr);
JNI()->ReleaseStringChars(jstr, jCharPtr);
}

View File

@ -441,6 +441,12 @@ public:
};
};
class nsJNIString : public nsString
{
public:
nsJNIString(jstring jstr);
};
}
#endif

View File

@ -99,6 +99,11 @@
#include <libosso.h>
#endif
#ifdef ANDROID
#include "AndroidBridge.h"
#include "nsIMIMEService.h"
#endif
#include "nsNativeCharsetUtils.h"
#include "nsTraceRefcntImpl.h"
@ -1801,6 +1806,18 @@ nsLocalFile::Launch()
return NS_ERROR_FAILURE;
#endif
#elif defined(ANDROID)
// Try to get a mimetype, if this fails just use the file uri alone
nsresult rv;
nsCAutoString type;
nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1", &rv));
if (NS_SUCCEEDED(rv))
rv = mimeService->GetTypeFromFile(this, type);
nsDependentCString fileUri = NS_LITERAL_CSTRING("file://");
fileUri.Append(mPath);
mozilla::AndroidBridge* bridge = mozilla::AndroidBridge::Bridge();
return bridge->OpenUriExternal(fileUri, type) ? NS_OK : NS_ERROR_FAILURE;
#else
return NS_ERROR_FAILURE;
#endif