2010-08-28 00:22:57 +04:00
|
|
|
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
|
|
|
* ***** BEGIN LICENSE BLOCK *****
|
2010-06-03 01:55:28 +04:00
|
|
|
* 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) 2009-2010
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
* Vladimir Vukicevic <vladimir@pobox.com>
|
2010-11-13 02:58:29 +03:00
|
|
|
* Matt Brubeck <mbrubeck@mozilla.com>
|
|
|
|
* Vivien Nicolas <vnicolas@mozilla.com>
|
2010-06-03 01:55:28 +04:00
|
|
|
*
|
|
|
|
* 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 ***** */
|
|
|
|
|
|
|
|
package org.mozilla.gecko;
|
|
|
|
|
|
|
|
import java.io.*;
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.zip.*;
|
|
|
|
import java.nio.*;
|
2010-09-14 05:16:24 +04:00
|
|
|
import java.nio.channels.FileChannel;
|
2010-09-30 19:37:36 +04:00
|
|
|
import java.util.concurrent.*;
|
2010-06-03 01:55:28 +04:00
|
|
|
|
|
|
|
import android.os.*;
|
|
|
|
import android.app.*;
|
|
|
|
import android.text.*;
|
|
|
|
import android.view.*;
|
|
|
|
import android.view.inputmethod.*;
|
|
|
|
import android.content.*;
|
2011-02-27 18:50:56 +03:00
|
|
|
import android.content.res.*;
|
2010-06-03 01:55:28 +04:00
|
|
|
import android.graphics.*;
|
|
|
|
import android.widget.*;
|
|
|
|
import android.hardware.*;
|
|
|
|
|
|
|
|
import android.util.*;
|
2010-09-30 19:37:36 +04:00
|
|
|
import android.net.*;
|
2011-06-02 04:40:38 +04:00
|
|
|
import android.database.*;
|
|
|
|
import android.provider.*;
|
2011-07-11 02:24:05 +04:00
|
|
|
import android.telephony.*;
|
2010-06-03 01:55:28 +04:00
|
|
|
|
|
|
|
abstract public class GeckoApp
|
|
|
|
extends Activity
|
|
|
|
{
|
2011-08-19 06:27:41 +04:00
|
|
|
private static final String LOG_FILE_NAME = "GeckoApp";
|
|
|
|
|
2010-06-15 06:17:37 +04:00
|
|
|
public static final String ACTION_ALERT_CLICK = "org.mozilla.gecko.ACTION_ALERT_CLICK";
|
|
|
|
public static final String ACTION_ALERT_CLEAR = "org.mozilla.gecko.ACTION_ALERT_CLEAR";
|
2011-08-08 07:30:32 +04:00
|
|
|
public static final String ACTION_WEBAPP = "org.mozilla.gecko.WEBAPP";
|
|
|
|
public static final String ACTION_DEBUG = "org.mozilla.gecko.DEBUG";
|
2011-08-09 06:37:57 +04:00
|
|
|
public static final String ACTION_BOOKMARK = "org.mozilla.gecko.BOOKMARK";
|
2010-06-15 06:17:37 +04:00
|
|
|
|
2010-06-03 01:55:28 +04:00
|
|
|
public static FrameLayout mainLayout;
|
|
|
|
public static GeckoSurfaceView surfaceView;
|
|
|
|
public static GeckoApp mAppContext;
|
2010-11-09 05:11:13 +03:00
|
|
|
public static boolean mFullscreen = false;
|
2011-02-08 07:40:42 +03:00
|
|
|
public static File sGREDir = null;
|
2011-01-11 08:48:35 +03:00
|
|
|
static Thread mLibLoadThread = null;
|
2011-03-31 08:13:35 +04:00
|
|
|
public Handler mMainHandler;
|
2011-05-09 23:58:55 +04:00
|
|
|
private IntentFilter mConnectivityFilter;
|
|
|
|
private BroadcastReceiver mConnectivityReceiver;
|
2011-07-11 02:24:05 +04:00
|
|
|
private PhoneStateListener mPhoneStateListener;
|
2010-06-03 01:55:28 +04:00
|
|
|
|
2010-11-25 01:51:41 +03:00
|
|
|
enum LaunchState {PreLaunch, Launching, WaitButton,
|
|
|
|
Launched, GeckoRunning, GeckoExiting};
|
|
|
|
private static LaunchState sLaunchState = LaunchState.PreLaunch;
|
2011-07-26 20:12:36 +04:00
|
|
|
private static boolean sTryCatchAttached = false;
|
2010-11-25 01:51:41 +03:00
|
|
|
|
2011-02-27 18:50:56 +03:00
|
|
|
|
2010-11-25 01:51:41 +03:00
|
|
|
static boolean checkLaunchState(LaunchState checkState) {
|
|
|
|
synchronized(sLaunchState) {
|
|
|
|
return sLaunchState == checkState;
|
|
|
|
}
|
|
|
|
}
|
2011-02-27 18:50:56 +03:00
|
|
|
|
2010-11-25 01:51:41 +03:00
|
|
|
static void setLaunchState(LaunchState setState) {
|
|
|
|
synchronized(sLaunchState) {
|
|
|
|
sLaunchState = setState;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if mLaunchState is equal to checkState this sets mLaunchState to setState
|
|
|
|
// and return true. Otherwise we return false.
|
|
|
|
static boolean checkAndSetLaunchState(LaunchState checkState, LaunchState setState) {
|
|
|
|
synchronized(sLaunchState) {
|
|
|
|
if (sLaunchState != checkState)
|
|
|
|
return false;
|
|
|
|
sLaunchState = setState;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-28 05:08:55 +04:00
|
|
|
void showErrorDialog(String message)
|
|
|
|
{
|
|
|
|
new AlertDialog.Builder(this)
|
|
|
|
.setMessage(message)
|
|
|
|
.setCancelable(false)
|
2011-02-12 01:35:50 +03:00
|
|
|
.setPositiveButton(R.string.exit_label,
|
2010-09-28 05:08:55 +04:00
|
|
|
new DialogInterface.OnClickListener() {
|
|
|
|
public void onClick(DialogInterface dialog,
|
|
|
|
int id)
|
|
|
|
{
|
|
|
|
GeckoApp.this.finish();
|
2011-02-12 01:35:50 +03:00
|
|
|
System.exit(0);
|
2010-09-28 05:08:55 +04:00
|
|
|
}
|
|
|
|
}).show();
|
|
|
|
}
|
|
|
|
|
2010-11-25 01:51:41 +03:00
|
|
|
// Returns true when the intent is going to be handled by gecko launch
|
2011-01-11 08:48:35 +03:00
|
|
|
boolean launch(Intent intent)
|
2010-06-03 01:55:28 +04:00
|
|
|
{
|
2010-11-25 01:51:41 +03:00
|
|
|
if (!checkAndSetLaunchState(LaunchState.Launching, LaunchState.Launched))
|
|
|
|
return false;
|
|
|
|
|
2011-01-11 08:48:35 +03:00
|
|
|
if (intent == null)
|
|
|
|
intent = getIntent();
|
|
|
|
final Intent i = intent;
|
2011-02-27 18:50:56 +03:00
|
|
|
new Thread() {
|
2011-01-11 08:48:35 +03:00
|
|
|
public void run() {
|
2011-02-09 22:58:17 +03:00
|
|
|
long startup_time = System.currentTimeMillis();
|
2011-01-11 08:48:35 +03:00
|
|
|
try {
|
|
|
|
if (mLibLoadThread != null)
|
|
|
|
mLibLoadThread.join();
|
|
|
|
} catch (InterruptedException ie) {}
|
2011-02-27 18:50:56 +03:00
|
|
|
surfaceView.mSplashStatusMsg =
|
2011-06-16 22:49:38 +04:00
|
|
|
getResources().getString(R.string.splash_screen_loading);
|
2011-01-11 08:48:35 +03:00
|
|
|
surfaceView.drawSplashScreen();
|
|
|
|
// unpack files in the components directory
|
|
|
|
try {
|
|
|
|
unpackComponents();
|
|
|
|
} catch (FileNotFoundException fnfe) {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.e(LOG_FILE_NAME, "error unpacking components", fnfe);
|
2011-01-11 08:48:35 +03:00
|
|
|
Looper.prepare();
|
|
|
|
showErrorDialog(getString(R.string.error_loading_file));
|
|
|
|
Looper.loop();
|
|
|
|
return;
|
|
|
|
} catch (IOException ie) {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.e(LOG_FILE_NAME, "error unpacking components", ie);
|
2011-01-11 08:48:35 +03:00
|
|
|
String msg = ie.getMessage();
|
|
|
|
Looper.prepare();
|
2011-03-01 07:24:42 +03:00
|
|
|
if (msg != null && msg.equalsIgnoreCase("No space left on device"))
|
2011-01-11 08:48:35 +03:00
|
|
|
showErrorDialog(getString(R.string.no_space_to_start_error));
|
|
|
|
else
|
|
|
|
showErrorDialog(getString(R.string.error_loading_file));
|
|
|
|
Looper.loop();
|
|
|
|
return;
|
|
|
|
}
|
2011-02-27 18:50:56 +03:00
|
|
|
|
2011-01-11 08:48:35 +03:00
|
|
|
// and then fire us up
|
2011-06-01 21:54:53 +04:00
|
|
|
try {
|
|
|
|
String env = i.getStringExtra("env0");
|
|
|
|
GeckoAppShell.runGecko(getApplication().getPackageResourcePath(),
|
|
|
|
i.getStringExtra("args"),
|
|
|
|
i.getDataString());
|
|
|
|
} catch (Exception e) {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.e(LOG_FILE_NAME, "top level exception", e);
|
2011-06-01 21:54:53 +04:00
|
|
|
StringWriter sw = new StringWriter();
|
|
|
|
e.printStackTrace(new PrintWriter(sw));
|
|
|
|
GeckoAppShell.reportJavaCrash(sw.toString());
|
|
|
|
}
|
2011-01-11 08:48:35 +03:00
|
|
|
}
|
|
|
|
}.start();
|
2010-11-25 01:51:41 +03:00
|
|
|
return true;
|
2010-06-03 01:55:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Called when the activity is first created. */
|
|
|
|
@Override
|
|
|
|
public void onCreate(Bundle savedInstanceState)
|
|
|
|
{
|
2011-02-27 18:50:56 +03:00
|
|
|
mAppContext = this;
|
2011-03-31 08:13:35 +04:00
|
|
|
mMainHandler = new Handler();
|
2011-02-27 18:50:56 +03:00
|
|
|
|
2011-07-26 20:12:36 +04:00
|
|
|
if (!sTryCatchAttached) {
|
|
|
|
sTryCatchAttached = true;
|
|
|
|
mMainHandler.post(new Runnable() {
|
|
|
|
public void run() {
|
|
|
|
try {
|
|
|
|
Looper.loop();
|
|
|
|
} catch (Exception e) {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.e(LOG_FILE_NAME, "top level exception", e);
|
2011-07-26 20:12:36 +04:00
|
|
|
StringWriter sw = new StringWriter();
|
|
|
|
e.printStackTrace(new PrintWriter(sw));
|
|
|
|
GeckoAppShell.reportJavaCrash(sw.toString());
|
|
|
|
}
|
|
|
|
// resetting this is kinda pointless, but oh well
|
|
|
|
sTryCatchAttached = false;
|
2011-06-01 21:54:53 +04:00
|
|
|
}
|
2011-07-26 20:12:36 +04:00
|
|
|
});
|
|
|
|
}
|
2011-06-01 21:54:53 +04:00
|
|
|
|
2011-02-27 18:50:56 +03:00
|
|
|
SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE);
|
|
|
|
String localeCode = settings.getString(getPackageName() + ".locale", "");
|
|
|
|
if (localeCode != null && localeCode.length() > 0)
|
|
|
|
GeckoAppShell.setSelectedLocale(localeCode);
|
|
|
|
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "create");
|
2010-06-03 01:55:28 +04:00
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
|
2011-02-08 11:39:15 +03:00
|
|
|
if (sGREDir == null)
|
|
|
|
sGREDir = new File(this.getApplicationInfo().dataDir);
|
2011-02-08 07:40:42 +03:00
|
|
|
|
2010-11-09 05:11:13 +03:00
|
|
|
getWindow().setFlags(mFullscreen ?
|
|
|
|
WindowManager.LayoutParams.FLAG_FULLSCREEN : 0,
|
|
|
|
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
2010-06-03 01:55:28 +04:00
|
|
|
|
2010-11-09 05:11:13 +03:00
|
|
|
if (surfaceView == null)
|
|
|
|
surfaceView = new GeckoSurfaceView(this);
|
|
|
|
else
|
|
|
|
mainLayout.removeView(surfaceView);
|
2010-09-14 05:16:24 +04:00
|
|
|
|
2010-06-03 01:55:28 +04:00
|
|
|
mainLayout = new FrameLayout(this);
|
|
|
|
mainLayout.addView(surfaceView,
|
|
|
|
new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,
|
|
|
|
FrameLayout.LayoutParams.FILL_PARENT));
|
|
|
|
|
|
|
|
setContentView(mainLayout,
|
|
|
|
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
|
|
|
|
ViewGroup.LayoutParams.FILL_PARENT));
|
2010-11-25 01:51:41 +03:00
|
|
|
|
2011-05-10 20:14:05 +04:00
|
|
|
mConnectivityFilter = new IntentFilter();
|
|
|
|
mConnectivityFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
|
|
|
mConnectivityReceiver = new GeckoConnectivityReceiver();
|
|
|
|
|
2011-07-11 02:24:05 +04:00
|
|
|
mPhoneStateListener = new GeckoPhoneStateListener();
|
|
|
|
|
2010-11-25 01:51:41 +03:00
|
|
|
if (!checkAndSetLaunchState(LaunchState.PreLaunch,
|
|
|
|
LaunchState.Launching))
|
|
|
|
return;
|
|
|
|
|
|
|
|
checkAndLaunchUpdate();
|
2011-02-27 18:50:56 +03:00
|
|
|
mLibLoadThread = new Thread(new Runnable() {
|
2011-01-11 08:48:35 +03:00
|
|
|
public void run() {
|
2011-02-27 18:50:56 +03:00
|
|
|
// At some point while loading the gecko libs our default locale gets set
|
|
|
|
// so just save it to locale here and reset it as default after the join
|
|
|
|
Locale locale = Locale.getDefault();
|
2011-01-11 08:48:35 +03:00
|
|
|
GeckoAppShell.loadGeckoLibs(
|
|
|
|
getApplication().getPackageResourcePath());
|
2011-02-27 18:50:56 +03:00
|
|
|
Locale.setDefault(locale);
|
|
|
|
Resources res = getBaseContext().getResources();
|
|
|
|
Configuration config = res.getConfiguration();
|
|
|
|
config.locale = locale;
|
|
|
|
res.updateConfiguration(config, res.getDisplayMetrics());
|
|
|
|
|
|
|
|
|
2011-01-11 08:48:35 +03:00
|
|
|
}});
|
2011-01-19 03:25:20 +03:00
|
|
|
File cacheFile = GeckoAppShell.getCacheDir();
|
|
|
|
File libxulFile = new File(cacheFile, "libxul.so");
|
|
|
|
|
|
|
|
if (GeckoAppShell.getFreeSpace() > GeckoAppShell.kFreeSpaceThreshold &&
|
2011-02-27 18:50:56 +03:00
|
|
|
(!libxulFile.exists() ||
|
2011-01-19 03:25:20 +03:00
|
|
|
new File(getApplication().getPackageResourcePath()).lastModified()
|
2011-07-18 22:25:20 +04:00
|
|
|
>= libxulFile.lastModified())) {
|
2011-01-11 08:48:35 +03:00
|
|
|
surfaceView.mSplashStatusMsg =
|
2011-06-16 22:49:38 +04:00
|
|
|
getResources().getString(R.string.splash_screen_installing_libs);
|
2011-07-18 22:25:20 +04:00
|
|
|
File[] libs = cacheFile.listFiles(new FilenameFilter() {
|
|
|
|
public boolean accept(File dir, String name) {
|
|
|
|
return name.endsWith(".so");
|
|
|
|
}
|
|
|
|
});
|
2011-07-20 20:37:54 +04:00
|
|
|
if (libs != null) {
|
|
|
|
for (int i = 0; i < libs.length; i++) {
|
|
|
|
libs[i].delete();
|
|
|
|
}
|
2011-07-18 22:25:20 +04:00
|
|
|
}
|
|
|
|
} else {
|
2011-01-11 08:48:35 +03:00
|
|
|
surfaceView.mSplashStatusMsg =
|
2011-06-16 22:49:38 +04:00
|
|
|
getResources().getString(R.string.splash_screen_loading);
|
2011-07-18 22:25:20 +04:00
|
|
|
}
|
2011-01-20 09:14:12 +03:00
|
|
|
mLibLoadThread.start();
|
2010-11-25 01:51:41 +03:00
|
|
|
}
|
|
|
|
|
2010-06-18 21:42:51 +04:00
|
|
|
@Override
|
|
|
|
protected void onNewIntent(Intent intent) {
|
2010-11-25 01:51:41 +03:00
|
|
|
if (checkLaunchState(LaunchState.GeckoExiting)) {
|
|
|
|
// We're exiting and shouldn't try to do anything else just incase
|
|
|
|
// we're hung for some reason we'll force the process to exit
|
|
|
|
System.exit(0);
|
|
|
|
return;
|
|
|
|
}
|
2010-06-18 21:42:51 +04:00
|
|
|
final String action = intent.getAction();
|
2011-08-08 07:30:32 +04:00
|
|
|
if (ACTION_DEBUG.equals(action) &&
|
2010-11-25 01:51:41 +03:00
|
|
|
checkAndSetLaunchState(LaunchState.Launching, LaunchState.WaitButton)) {
|
|
|
|
final Button launchButton = new Button(this);
|
|
|
|
launchButton.setText("Launch"); // don't need to localize
|
|
|
|
launchButton.setOnClickListener(new Button.OnClickListener() {
|
2011-02-27 18:50:56 +03:00
|
|
|
public void onClick (View v) {
|
|
|
|
// hide the button so we can't be launched again
|
|
|
|
mainLayout.removeView(launchButton);
|
|
|
|
setLaunchState(LaunchState.Launching);
|
|
|
|
launch(null);
|
|
|
|
}
|
|
|
|
});
|
2010-11-25 01:51:41 +03:00
|
|
|
mainLayout.addView(launchButton, 300, 200);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (checkLaunchState(LaunchState.WaitButton) || launch(intent))
|
|
|
|
return;
|
|
|
|
|
2011-08-09 06:37:57 +04:00
|
|
|
if (Intent.ACTION_MAIN.equals(action)) {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "Intent : ACTION_MAIN");
|
2011-08-09 06:37:57 +04:00
|
|
|
GeckoAppShell.sendEventToGecko(new GeckoEvent(""));
|
|
|
|
}
|
|
|
|
else if (Intent.ACTION_VIEW.equals(action)) {
|
2010-06-18 21:42:51 +04:00
|
|
|
String uri = intent.getDataString();
|
|
|
|
GeckoAppShell.sendEventToGecko(new GeckoEvent(uri));
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME,"onNewIntent: "+uri);
|
2010-06-18 21:42:51 +04:00
|
|
|
}
|
2011-08-08 07:30:32 +04:00
|
|
|
else if (ACTION_WEBAPP.equals(action)) {
|
2010-10-15 22:16:45 +04:00
|
|
|
String uri = intent.getStringExtra("args");
|
|
|
|
GeckoAppShell.sendEventToGecko(new GeckoEvent(uri));
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME,"Intent : WEBAPP - " + uri);
|
2010-10-15 22:16:45 +04:00
|
|
|
}
|
2011-08-09 06:37:57 +04:00
|
|
|
else if (ACTION_BOOKMARK.equals(action)) {
|
|
|
|
String args = intent.getStringExtra("args");
|
|
|
|
GeckoAppShell.sendEventToGecko(new GeckoEvent(args));
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME,"Intent : BOOKMARK - " + args);
|
2011-08-09 06:37:57 +04:00
|
|
|
}
|
2010-06-18 21:42:51 +04:00
|
|
|
}
|
|
|
|
|
2010-06-03 01:55:28 +04:00
|
|
|
@Override
|
|
|
|
public void onPause()
|
|
|
|
{
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "pause");
|
2010-06-18 01:33:15 +04:00
|
|
|
GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_PAUSING));
|
2010-06-03 01:55:28 +04:00
|
|
|
// The user is navigating away from this activity, but nothing
|
|
|
|
// has come to the foreground yet; for Gecko, we may want to
|
|
|
|
// stop repainting, for example.
|
|
|
|
|
|
|
|
// Whatever we do here should be fast, because we're blocking
|
|
|
|
// the next activity from showing up until we finish.
|
|
|
|
|
|
|
|
// onPause will be followed by either onResume or onStop.
|
|
|
|
super.onPause();
|
2011-05-09 23:58:55 +04:00
|
|
|
|
|
|
|
unregisterReceiver(mConnectivityReceiver);
|
2011-07-11 02:24:05 +04:00
|
|
|
|
|
|
|
TelephonyManager tm = (TelephonyManager)
|
|
|
|
GeckoApp.mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
|
|
|
|
tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
|
2010-06-03 01:55:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onResume()
|
|
|
|
{
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "resume");
|
2010-11-25 01:51:41 +03:00
|
|
|
if (checkLaunchState(LaunchState.GeckoRunning))
|
2011-02-02 09:34:12 +03:00
|
|
|
GeckoAppShell.onResume();
|
2010-06-03 01:55:28 +04:00
|
|
|
// After an onPause, the activity is back in the foreground.
|
|
|
|
// Undo whatever we did in onPause.
|
|
|
|
super.onResume();
|
2010-11-25 01:51:41 +03:00
|
|
|
|
|
|
|
// Just in case. Normally we start in onNewIntent
|
|
|
|
if (checkLaunchState(LaunchState.PreLaunch) ||
|
|
|
|
checkLaunchState(LaunchState.Launching))
|
|
|
|
onNewIntent(getIntent());
|
2011-05-09 23:58:55 +04:00
|
|
|
|
|
|
|
registerReceiver(mConnectivityReceiver, mConnectivityFilter);
|
2011-07-11 02:24:05 +04:00
|
|
|
|
|
|
|
TelephonyManager tm = (TelephonyManager)
|
|
|
|
GeckoApp.mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
|
|
|
|
tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
|
|
|
|
|
|
|
|
// Notify if network state changed since we paused
|
|
|
|
GeckoAppShell.onNetworkStateChange(true);
|
2011-02-02 09:34:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onStop()
|
|
|
|
{
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "stop");
|
2011-02-02 09:34:12 +03:00
|
|
|
// We're about to be stopped, potentially in preparation for
|
|
|
|
// being destroyed. We're killable after this point -- as I
|
|
|
|
// understand it, in extreme cases the process can be terminated
|
|
|
|
// without going through onDestroy.
|
|
|
|
//
|
|
|
|
// We might also get an onRestart after this; not sure what
|
|
|
|
// that would mean for Gecko if we were to kill it here.
|
|
|
|
// Instead, what we should do here is save prefs, session,
|
|
|
|
// etc., and generally mark the profile as 'clean', and then
|
|
|
|
// dirty it again if we get an onResume.
|
|
|
|
|
2011-07-28 10:25:11 +04:00
|
|
|
|
2011-02-02 09:34:12 +03:00
|
|
|
GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_STOPPING));
|
|
|
|
super.onStop();
|
2011-07-28 10:25:11 +04:00
|
|
|
GeckoAppShell.putChildInBackground();
|
2011-02-02 09:34:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onRestart()
|
|
|
|
{
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "restart");
|
2011-07-28 10:25:11 +04:00
|
|
|
GeckoAppShell.putChildInForeground();
|
2011-02-02 09:34:12 +03:00
|
|
|
super.onRestart();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onStart()
|
|
|
|
{
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "start");
|
2011-08-21 23:11:31 +04:00
|
|
|
GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_START));
|
2011-02-02 09:34:12 +03:00
|
|
|
super.onStart();
|
2010-06-24 23:00:42 +04:00
|
|
|
}
|
|
|
|
|
2010-06-03 01:55:28 +04:00
|
|
|
@Override
|
|
|
|
public void onDestroy()
|
|
|
|
{
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "destroy");
|
2010-06-03 01:55:28 +04:00
|
|
|
// Tell Gecko to shutting down; we'll end up calling System.exit()
|
|
|
|
// in onXreExit.
|
2010-11-09 05:11:18 +03:00
|
|
|
if (isFinishing())
|
2010-12-12 01:36:11 +03:00
|
|
|
GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_SHUTDOWN));
|
2010-06-03 01:55:28 +04:00
|
|
|
|
|
|
|
super.onDestroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onConfigurationChanged(android.content.res.Configuration newConfig)
|
|
|
|
{
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "configuration changed");
|
2010-06-03 01:55:28 +04:00
|
|
|
// nothing, just ignore
|
|
|
|
super.onConfigurationChanged(newConfig);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onLowMemory()
|
|
|
|
{
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.e(LOG_FILE_NAME, "low memory");
|
2010-11-25 01:51:41 +03:00
|
|
|
if (checkLaunchState(LaunchState.GeckoRunning))
|
2010-08-31 21:37:54 +04:00
|
|
|
GeckoAppShell.onLowMemory();
|
2010-06-03 01:55:28 +04:00
|
|
|
super.onLowMemory();
|
|
|
|
}
|
|
|
|
|
2010-12-21 23:02:14 +03:00
|
|
|
abstract public String getPackageName();
|
2010-06-26 00:12:03 +04:00
|
|
|
abstract public String getContentProcessName();
|
2010-06-03 01:55:28 +04:00
|
|
|
|
|
|
|
protected void unpackComponents()
|
2010-09-30 19:53:42 +04:00
|
|
|
throws IOException, FileNotFoundException
|
2010-06-03 01:55:28 +04:00
|
|
|
{
|
|
|
|
ZipFile zip;
|
|
|
|
InputStream listStream;
|
|
|
|
|
2011-02-08 07:40:42 +03:00
|
|
|
File componentsDir = new File(sGREDir, "components");
|
2010-09-30 19:53:42 +04:00
|
|
|
componentsDir.mkdir();
|
|
|
|
zip = new ZipFile(getApplication().getPackageResourcePath());
|
2010-09-02 05:35:46 +04:00
|
|
|
|
|
|
|
byte[] buf = new byte[8192];
|
2011-03-18 18:50:19 +03:00
|
|
|
try {
|
|
|
|
if (unpackFile(zip, buf, null, "removed-files"))
|
|
|
|
removeFiles();
|
|
|
|
} catch (Exception ex) {
|
|
|
|
// This file may not be there, so just log any errors and move on
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.w(LOG_FILE_NAME, "error removing files", ex);
|
2011-03-18 18:50:19 +03:00
|
|
|
}
|
2010-09-02 05:35:46 +04:00
|
|
|
unpackFile(zip, buf, null, "application.ini");
|
|
|
|
unpackFile(zip, buf, null, getContentProcessName());
|
|
|
|
try {
|
2010-09-30 19:53:42 +04:00
|
|
|
unpackFile(zip, buf, null, "update.locale");
|
|
|
|
} catch (Exception e) {/* this is non-fatal */}
|
2010-06-03 01:55:28 +04:00
|
|
|
|
2010-09-30 21:19:05 +04:00
|
|
|
// copy any .xpi file into an extensions/ directory
|
|
|
|
Enumeration<? extends ZipEntry> zipEntries = zip.entries();
|
|
|
|
while (zipEntries.hasMoreElements()) {
|
|
|
|
ZipEntry entry = zipEntries.nextElement();
|
|
|
|
if (entry.getName().startsWith("extensions/") && entry.getName().endsWith(".xpi")) {
|
|
|
|
Log.i("GeckoAppJava", "installing extension : " + entry.getName());
|
|
|
|
unpackFile(zip, buf, entry, entry.getName());
|
|
|
|
}
|
|
|
|
}
|
2011-05-05 19:03:01 +04:00
|
|
|
|
|
|
|
// copy any hyphenation dictionaries file into a hyphenation/ directory
|
|
|
|
Enumeration<? extends ZipEntry> hyphenEntries = zip.entries();
|
|
|
|
while (hyphenEntries.hasMoreElements()) {
|
|
|
|
ZipEntry entry = hyphenEntries.nextElement();
|
|
|
|
if (entry.getName().startsWith("hyphenation/")) {
|
|
|
|
Log.i("GeckoAppJava", "installing hyphenation : " + entry.getName());
|
|
|
|
unpackFile(zip, buf, entry, entry.getName());
|
|
|
|
}
|
|
|
|
}
|
2010-06-03 01:55:28 +04:00
|
|
|
}
|
|
|
|
|
2011-03-18 18:50:19 +03:00
|
|
|
void removeFiles() throws IOException {
|
|
|
|
BufferedReader reader = new BufferedReader(
|
|
|
|
new FileReader(new File(sGREDir, "removed-files")));
|
|
|
|
try {
|
|
|
|
for (String removedFileName = reader.readLine();
|
|
|
|
removedFileName != null; removedFileName = reader.readLine()) {
|
|
|
|
File removedFile = new File(sGREDir, removedFileName);
|
|
|
|
if (removedFile.exists())
|
|
|
|
removedFile.delete();
|
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
reader.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-03-05 02:00:52 +03:00
|
|
|
boolean haveKilledZombies = false;
|
|
|
|
|
2011-03-18 18:50:19 +03:00
|
|
|
private boolean unpackFile(ZipFile zip, byte[] buf, ZipEntry fileEntry,
|
2010-09-30 19:53:42 +04:00
|
|
|
String name)
|
|
|
|
throws IOException, FileNotFoundException
|
2010-06-03 01:55:28 +04:00
|
|
|
{
|
|
|
|
if (fileEntry == null)
|
|
|
|
fileEntry = zip.getEntry(name);
|
2010-09-30 19:53:42 +04:00
|
|
|
if (fileEntry == null)
|
|
|
|
throw new FileNotFoundException("Can't find " + name + " in " +
|
|
|
|
zip.getName());
|
2010-06-03 01:55:28 +04:00
|
|
|
|
2011-02-08 07:40:42 +03:00
|
|
|
File outFile = new File(sGREDir, name);
|
2010-06-03 01:55:28 +04:00
|
|
|
if (outFile.exists() &&
|
2010-10-06 03:48:33 +04:00
|
|
|
outFile.lastModified() == fileEntry.getTime() &&
|
2010-06-03 01:55:28 +04:00
|
|
|
outFile.length() == fileEntry.getSize())
|
2011-03-18 18:50:19 +03:00
|
|
|
return false;
|
2010-06-03 01:55:28 +04:00
|
|
|
|
2011-05-20 22:44:09 +04:00
|
|
|
surfaceView.mSplashStatusMsg =
|
|
|
|
getResources().getString(R.string.splash_firstrun);
|
|
|
|
surfaceView.drawSplashScreen();
|
|
|
|
|
2011-03-05 02:00:52 +03:00
|
|
|
if (!haveKilledZombies) {
|
|
|
|
haveKilledZombies = true;
|
|
|
|
GeckoAppShell.killAnyZombies();
|
|
|
|
}
|
2011-02-22 21:38:13 +03:00
|
|
|
|
2010-09-30 19:53:42 +04:00
|
|
|
File dir = outFile.getParentFile();
|
|
|
|
if (!outFile.exists())
|
|
|
|
dir.mkdirs();
|
2010-06-03 01:55:28 +04:00
|
|
|
|
|
|
|
InputStream fileStream;
|
2010-09-30 19:53:42 +04:00
|
|
|
fileStream = zip.getInputStream(fileEntry);
|
2010-06-03 01:55:28 +04:00
|
|
|
|
2010-09-30 19:53:42 +04:00
|
|
|
OutputStream outStream = new FileOutputStream(outFile);
|
2010-06-03 01:55:28 +04:00
|
|
|
|
2010-09-30 19:53:42 +04:00
|
|
|
while (fileStream.available() > 0) {
|
|
|
|
int read = fileStream.read(buf, 0, buf.length);
|
|
|
|
outStream.write(buf, 0, read);
|
2010-06-03 01:55:28 +04:00
|
|
|
}
|
2010-09-18 04:37:28 +04:00
|
|
|
|
2010-09-30 19:53:42 +04:00
|
|
|
fileStream.close();
|
|
|
|
outStream.close();
|
2010-09-18 04:37:28 +04:00
|
|
|
outFile.setLastModified(fileEntry.getTime());
|
2011-03-18 18:50:19 +03:00
|
|
|
return true;
|
2010-06-03 01:55:28 +04:00
|
|
|
}
|
2010-09-30 19:53:42 +04:00
|
|
|
|
2010-10-25 00:26:19 +04:00
|
|
|
public void addEnvToIntent(Intent intent) {
|
2010-06-03 01:55:28 +04:00
|
|
|
Map<String,String> envMap = System.getenv();
|
|
|
|
Set<Map.Entry<String,String>> envSet = envMap.entrySet();
|
|
|
|
Iterator<Map.Entry<String,String>> envIter = envSet.iterator();
|
|
|
|
StringBuffer envstr = new StringBuffer();
|
|
|
|
int c = 0;
|
|
|
|
while (envIter.hasNext()) {
|
|
|
|
Map.Entry<String,String> entry = envIter.next();
|
2011-02-27 18:50:56 +03:00
|
|
|
intent.putExtra("env" + c, entry.getKey() + "="
|
2010-10-25 00:26:19 +04:00
|
|
|
+ entry.getValue());
|
|
|
|
c++;
|
2010-06-03 01:55:28 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void doRestart() {
|
|
|
|
try {
|
2010-12-21 23:02:14 +03:00
|
|
|
String action = "org.mozilla.gecko.restart";
|
2010-10-25 00:26:19 +04:00
|
|
|
Intent intent = new Intent(action);
|
2010-12-21 23:02:14 +03:00
|
|
|
intent.setClassName(getPackageName(),
|
|
|
|
getPackageName() + ".Restarter");
|
2010-10-25 00:26:19 +04:00
|
|
|
addEnvToIntent(intent);
|
2010-12-02 19:46:22 +03:00
|
|
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
|
|
|
|
Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, intent.toString());
|
2011-03-05 02:00:52 +03:00
|
|
|
GeckoAppShell.killAnyZombies();
|
2010-10-27 05:57:29 +04:00
|
|
|
startActivity(intent);
|
2010-06-03 01:55:28 +04:00
|
|
|
} catch (Exception e) {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "error doing restart", e);
|
2010-06-03 01:55:28 +04:00
|
|
|
}
|
2010-10-25 00:26:19 +04:00
|
|
|
finish();
|
2011-03-01 01:10:40 +03:00
|
|
|
// Give the restart process time to start before we die
|
2011-03-05 02:00:52 +03:00
|
|
|
GeckoAppShell.waitForAnotherGeckoProc();
|
2010-06-03 01:55:28 +04:00
|
|
|
}
|
2010-06-15 06:17:37 +04:00
|
|
|
|
|
|
|
public void handleNotification(String action, String alertName, String alertCookie) {
|
|
|
|
GeckoAppShell.handleNotification(action, alertName, alertCookie);
|
|
|
|
}
|
2010-09-14 05:16:24 +04:00
|
|
|
|
|
|
|
private void checkAndLaunchUpdate() {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "Checking for an update");
|
2010-09-14 05:16:24 +04:00
|
|
|
|
|
|
|
int statusCode = 8; // UNEXPECTED_ERROR
|
2011-02-10 02:22:35 +03:00
|
|
|
File baseUpdateDir = null;
|
2011-01-04 01:32:57 +03:00
|
|
|
if (Build.VERSION.SDK_INT >= 8)
|
2011-02-10 02:22:35 +03:00
|
|
|
baseUpdateDir = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
|
2011-01-04 01:32:57 +03:00
|
|
|
else
|
2011-02-10 02:22:35 +03:00
|
|
|
baseUpdateDir = new File(Environment.getExternalStorageDirectory().getPath(), "download");
|
2011-01-04 01:32:57 +03:00
|
|
|
|
2011-02-10 02:22:35 +03:00
|
|
|
File updateDir = new File(new File(baseUpdateDir, "updates"),"0");
|
2010-09-14 05:16:24 +04:00
|
|
|
|
2011-01-04 01:32:57 +03:00
|
|
|
File updateFile = new File(updateDir, "update.apk");
|
|
|
|
File statusFile = new File(updateDir, "update.status");
|
2010-11-19 01:13:31 +03:00
|
|
|
|
|
|
|
if (!statusFile.exists() || !readUpdateStatus(statusFile).equals("pending"))
|
|
|
|
return;
|
2010-09-14 05:16:24 +04:00
|
|
|
|
|
|
|
if (!updateFile.exists())
|
|
|
|
return;
|
|
|
|
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "Update is available!");
|
2010-09-14 05:16:24 +04:00
|
|
|
|
|
|
|
// Launch APK
|
2011-06-09 01:33:49 +04:00
|
|
|
File updateFileToRun = new File(updateDir, getPackageName() + "-update.apk");
|
2010-09-14 05:16:24 +04:00
|
|
|
try {
|
2010-09-17 22:03:43 +04:00
|
|
|
if (updateFile.renameTo(updateFileToRun)) {
|
2010-09-14 05:16:24 +04:00
|
|
|
String amCmd = "/system/bin/am start -a android.intent.action.VIEW " +
|
|
|
|
"-n com.android.packageinstaller/.PackageInstallerActivity -d file://" +
|
|
|
|
updateFileToRun.getPath();
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, amCmd);
|
2010-09-14 05:16:24 +04:00
|
|
|
Runtime.getRuntime().exec(amCmd);
|
|
|
|
statusCode = 0; // OK
|
|
|
|
} else {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "Cannot rename the update file!");
|
2010-09-14 05:16:24 +04:00
|
|
|
statusCode = 7; // WRITE_ERROR
|
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "error launching installer to update", e);
|
2010-09-14 05:16:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Update the status file
|
|
|
|
String status = statusCode == 0 ? "succeeded\n" : "failed: "+ statusCode + "\n";
|
|
|
|
|
|
|
|
OutputStream outStream;
|
|
|
|
try {
|
|
|
|
byte[] buf = status.getBytes("UTF-8");
|
|
|
|
outStream = new FileOutputStream(statusFile);
|
|
|
|
outStream.write(buf, 0, buf.length);
|
|
|
|
outStream.close();
|
|
|
|
} catch (Exception e) {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "error writing status file", e);
|
2010-09-14 05:16:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (statusCode == 0)
|
|
|
|
System.exit(0);
|
|
|
|
}
|
2010-09-30 19:37:36 +04:00
|
|
|
|
2010-11-19 01:13:31 +03:00
|
|
|
private String readUpdateStatus(File statusFile) {
|
|
|
|
String status = "";
|
|
|
|
try {
|
|
|
|
BufferedReader reader = new BufferedReader(new FileReader(statusFile));
|
|
|
|
status = reader.readLine();
|
|
|
|
reader.close();
|
|
|
|
} catch (Exception e) {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "error reading update status", e);
|
2010-11-19 01:13:31 +03:00
|
|
|
}
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2010-09-30 19:37:36 +04:00
|
|
|
static final int FILE_PICKER_REQUEST = 1;
|
|
|
|
|
|
|
|
private SynchronousQueue<String> mFilePickerResult = new SynchronousQueue();
|
2010-11-05 20:43:12 +03:00
|
|
|
public String showFilePicker(String aMimeType) {
|
2010-09-30 19:37:36 +04:00
|
|
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
|
|
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
2010-11-05 20:43:12 +03:00
|
|
|
intent.setType(aMimeType);
|
2010-09-30 19:37:36 +04:00
|
|
|
GeckoApp.this.
|
|
|
|
startActivityForResult(
|
2011-08-02 05:17:14 +04:00
|
|
|
Intent.createChooser(intent, getString(R.string.choose_file)),
|
2010-09-30 19:37:36 +04:00
|
|
|
FILE_PICKER_REQUEST);
|
|
|
|
String filePickerResult = "";
|
2011-08-19 06:30:22 +04:00
|
|
|
|
2010-09-30 19:37:36 +04:00
|
|
|
try {
|
2011-08-19 06:30:22 +04:00
|
|
|
while (null == (filePickerResult = mFilePickerResult.poll(1, TimeUnit.MILLISECONDS))) {
|
|
|
|
Log.i("GeckoApp", "processing events from showFilePicker ");
|
|
|
|
GeckoAppShell.processNextNativeEvent();
|
|
|
|
}
|
2010-09-30 19:37:36 +04:00
|
|
|
} catch (InterruptedException e) {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "showing file picker ", e);
|
2010-09-30 19:37:36 +04:00
|
|
|
}
|
2011-02-27 18:50:56 +03:00
|
|
|
|
2010-09-30 19:37:36 +04:00
|
|
|
return filePickerResult;
|
|
|
|
}
|
2011-02-27 18:50:56 +03:00
|
|
|
|
2010-09-30 19:37:36 +04:00
|
|
|
@Override
|
2011-02-27 18:50:56 +03:00
|
|
|
protected void onActivityResult(int requestCode, int resultCode,
|
2010-09-30 19:37:36 +04:00
|
|
|
Intent data) {
|
|
|
|
String filePickerResult = "";
|
|
|
|
if (data != null && resultCode == RESULT_OK) {
|
|
|
|
try {
|
|
|
|
ContentResolver cr = getContentResolver();
|
|
|
|
Uri uri = data.getData();
|
2011-06-02 04:40:38 +04:00
|
|
|
Cursor cursor = GeckoApp.mAppContext.getContentResolver().query(
|
|
|
|
uri,
|
|
|
|
new String[] { OpenableColumns.DISPLAY_NAME },
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null);
|
|
|
|
String name = null;
|
|
|
|
if (cursor != null) {
|
|
|
|
try {
|
|
|
|
if (cursor.moveToNext()) {
|
|
|
|
name = cursor.getString(0);
|
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
String fileName = "tmp_";
|
|
|
|
String fileExt = null;
|
|
|
|
int period;
|
|
|
|
if (name == null || (period = name.lastIndexOf('.')) == -1) {
|
|
|
|
String mimeType = cr.getType(uri);
|
|
|
|
fileExt = "." + GeckoAppShell.getExtensionFromMimeType(mimeType);
|
|
|
|
} else {
|
|
|
|
fileExt = name.substring(period);
|
|
|
|
fileName = name.substring(0, period);
|
|
|
|
}
|
|
|
|
File file = File.createTempFile(fileName, fileExt, sGREDir);
|
2011-02-27 18:50:56 +03:00
|
|
|
|
2010-09-30 19:37:36 +04:00
|
|
|
FileOutputStream fos = new FileOutputStream(file);
|
|
|
|
InputStream is = cr.openInputStream(uri);
|
|
|
|
byte[] buf = new byte[4096];
|
|
|
|
int len = is.read(buf);
|
|
|
|
while (len != -1) {
|
|
|
|
fos.write(buf, 0, len);
|
|
|
|
len = is.read(buf);
|
|
|
|
}
|
|
|
|
fos.close();
|
|
|
|
filePickerResult = file.getAbsolutePath();
|
|
|
|
}catch (Exception e) {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.e(LOG_FILE_NAME, "showing file picker", e);
|
2010-09-30 19:37:36 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
mFilePickerResult.put(filePickerResult);
|
|
|
|
} catch (InterruptedException e) {
|
2011-08-19 06:27:41 +04:00
|
|
|
Log.i(LOG_FILE_NAME, "error returning file picker result", e);
|
2010-09-30 19:37:36 +04:00
|
|
|
}
|
|
|
|
}
|
2010-06-03 01:55:28 +04:00
|
|
|
}
|