Permalink
Browse files

Merge remote branch 'upstream/master' into system

  • Loading branch information...
2 parents d9c9b36 + 147a2ce commit 2c3b925ab997532631bd7557dcfe34fed7ac975a @vingtetun vingtetun committed Apr 26, 2012
View
@@ -8,3 +8,4 @@ apps/settings/gaia-commit.txt
profile/
xulrunner/
xulrunner-sdk/
+apps/homescreen/apps-manifest-fallback.json
View
@@ -81,6 +81,9 @@ profile: stamp-commit-hash update-offline-manifests preferences manifests offlin
LANG=POSIX # Avoiding sort order differences between OSes
+desktop-fallback-manifest:
+ sh tools/create-desktop-apps.sh
+
# Generate profile/webapps/
manifests:
@echo "Generated webapps"
@@ -114,7 +117,7 @@ offline: install-xulrunner
@rm -rf profile/OfflineCache
@mkdir -p profile/OfflineCache
@cd ..
- $(XULRUNNER) $(XPCSHELL) -e 'const GAIA_DIR = "$(CURDIR)"; const PROFILE_DIR = "$(CURDIR)/profile"; const GAIA_DOMAIN = "$(GAIA_DOMAIN)$(GAIA_PORT)"' offline-cache.js
+ $(XULRUNNER) $(XPCSHELL) -e 'const GAIA_DIR = "$(CURDIR)"; const PROFILE_DIR = "$(CURDIR)/profile"; const GAIA_DOMAIN = "$(GAIA_DOMAIN)$(GAIA_PORT)"' build/offline-cache.js
@echo "Done"
# The install-xulrunner target arranges to get xulrunner downloaded and sets up
@@ -145,7 +148,7 @@ endif
preferences: install-xulrunner
@echo "Generating prefs.js..."
@mkdir -p profile
- $(XULRUNNER) $(XPCSHELL) -e 'const GAIA_DIR = "$(CURDIR)"; const PROFILE_DIR = "$(CURDIR)/profile"; const GAIA_DOMAIN = "$(GAIA_DOMAIN)$(GAIA_PORT)"; const DEBUG = $(DEBUG)' preferences.js
+ $(XULRUNNER) $(XPCSHELL) -e 'const GAIA_DIR = "$(CURDIR)"; const PROFILE_DIR = "$(CURDIR)/profile"; const GAIA_DOMAIN = "$(GAIA_DOMAIN)$(GAIA_PORT)"; const DEBUG = $(DEBUG)' build/preferences.js
@echo "Done"
@@ -262,20 +265,15 @@ update-offline-manifests:
fi \
done
-
# If your gaia/ directory is a sub-directory of the B2G directory, then
# you should use the install-gaia target of the B2G Makefile. But if you're
# working on just gaia itself, and you already have B2G firmware on your
# phone, and you have adb in your path, then you can use the install-gaia
# target to update the gaia files and reboot b2g
install-gaia: profile
$(ADB) start-server
- $(ADB) shell rm -r /data/local/*
$(ADB) shell rm -r /cache/*
- # just push the profile
- $(ADB) push profile/OfflineCache /data/local/OfflineCache
- $(ADB) push profile/webapps /data/local/webapps
- $(ADB) push profile/user.js /data/local/user.js
+ python build/install-gaia.py "$(ADB)"
@echo "Installed gaia into profile/."
$(ADB) shell kill $(shell $(ADB) shell toolbox ps | grep "b2g" | awk '{ print $$2; }')
@echo 'Rebooting b2g now'
View
@@ -21,3 +21,7 @@ and talk to us on IRC:
#B2G on irc.mozilla.org
See INSTALL file in B2G repository for instructions on building and running B2G.
+
+## Desktop
+
+Make sure to run `make desktop` before running gaia in firefox
@@ -16,6 +16,12 @@ edit=Edit
send=Send
newMessage=New Message
+[es]
+messages=Mensajes
+edit=Editar
+send=Enviar
+newMessage=Nuevo Mensaje
+
[fr]
messages=Messages
edit=Modifier
View
@@ -0,0 +1,153 @@
+"""Usage: python %prog [ADB_PATH]
+
+ADB_PATH is the path to the |adb| executable we should run.
+
+Used by |make install-gaia| to push files to a device. You shouldn't run
+this file directly.
+
+"""
+
+import sys
+import os
+import hashlib
+import subprocess
+from tempfile import mkstemp
+
+def compute_local_hash(filename, hashes):
+ h = hashlib.sha1()
+ with open(filename,'rb') as f:
+ for chunk in iter(lambda: f.read(256 * h.block_size), b''):
+ h.update(chunk)
+ hashes[filename] = h.hexdigest()
+
+def compute_local_hashes_in_dir(dir, hashes):
+ def visit(arg, dirname, names):
+ for filename in [os.path.join(dirname, name) for name in names]:
+ if not os.path.isfile(filename):
+ continue
+ compute_local_hash(filename, hashes)
+
+ os.path.walk(dir, visit, None)
+
+def compute_local_hashes():
+ hashes = {}
+ compute_local_hashes_in_dir('webapps', hashes)
+ compute_local_hashes_in_dir('OfflineCache', hashes)
+ compute_local_hash('user.js', hashes)
+ return hashes
+
+def adb_push(local, remote):
+ global adb_cmd
+ subprocess.check_call([adb_cmd, 'push', local, remote])
+
+def adb_shell(cmd):
+ global adb_cmd
+
+ # Output the return code so we can check whether the command executed
+ # successfully.
+ new_cmd = cmd + '; echo "RETURN CODE: $?"'
+
+ # universal_newlines=True because adb shell returns CRLF separators.
+ proc = subprocess.Popen([adb_cmd, 'shell', new_cmd],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ universal_newlines=True)
+ (stdout, stderr) = proc.communicate()
+ if stderr.strip():
+ raise Exception('adb shell "%s" returned the following unexpected error: "%s"' %
+ (cmd, stderr.strip()))
+ if proc.returncode != 0:
+ raise Exception('adb shell "%s" exited with error %d' % (cmd, proc.returncode))
+
+ split = [line for line in stdout.split('\n') if line.strip()]
+ if not split[-1].startswith('RETURN CODE: 0'):
+ raise Exception('adb shell "%s" did not complete successfully. Output:\n%s' % (cmd, stdout))
+
+ # Don't return the "RETURN CODE: 0" line!
+ return split[0:-1]
+
+
+def compute_remote_hashes():
+ hashes = {}
+ adb_out = adb_shell('cd /data/local && find . -type f | xargs sha1sum')
+ for (hash, filename) in [line.split() for line in adb_out]:
+ # Strip off './' from the filename.
+ if filename.startswith('./'):
+ filename = filename[2:]
+ else:
+ raise Exception('Unexpected filename %s' % filename)
+
+ hashes[filename] = hash
+ return hashes
+
+def remove_from_remote(local_hashes, remote_hashes):
+ """Remove any files from the remote device which don't appear in
+ local_hashes.
+
+ """
+ to_remove = list(set(remote_hashes.keys()) - set(local_hashes.keys()))
+ if not to_remove:
+ return
+ print 'Removing from device:\n%s\n' % '\n'.join(to_remove)
+ # Chunk to_remove into 25 files at a time so we don't send too much over
+ # adb_shell at once.
+ for files in [to_remove[pos:pos + 25] for pos in xrange(0, len(to_remove), 25)]:
+ adb_shell('cd /data/local && rm -f %s' % ' '.join(files))
+
+def push_to_remote(local_hashes, remote_hashes):
+ global adb_cmd
+
+ to_push = set()
+ for (k, v) in local_hashes.items():
+ if k not in remote_hashes or remote_hashes[k] != local_hashes[k]:
+ to_push.add(k)
+
+ if not to_push:
+ return
+
+ print 'Pushing to device:\n%s' % '\n'.join(list(to_push))
+
+ tmpfile, tmpfilename = mkstemp()
+ try:
+ subprocess.check_call(['tar', '-czf', tmpfilename] + list(to_push))
+ adb_push(tmpfilename, '/data/local')
+ basename = os.path.basename(tmpfilename)
+ adb_shell('cd /data/local && tar -xzf %s && rm %s' % (basename, basename))
+ finally:
+ os.remove(tmpfilename)
+
+def install_gaia_fast():
+ os.chdir('profile')
+ try:
+ local_hashes = compute_local_hashes()
+ remote_hashes = compute_remote_hashes()
+ remove_from_remote(local_hashes, remote_hashes)
+ push_to_remote(local_hashes, remote_hashes)
+ finally:
+ os.chdir('..')
+
+def install_gaia_slow():
+ global adb_cmd
+ adb_shell("rm -r /data/local/*")
+ adb_push('profile/OfflineCache', '/data/local/OfflineCache')
+ adb_push('profile/webapps', '/data/local/webapps')
+ adb_push('profile/user.js', '/data/local')
+
+def install_gaia():
+ try:
+ install_gaia_fast()
+ except:
+ # If anything goes wrong, fall back to the slow method.
+ install_gaia_slow()
+
+if __name__ == '__main__':
+ if len(sys.argv) > 2:
+ print 'Too many arguments! Usage: python %s [ADB_PATH]' % __FILE__
+ sys.exit(1)
+
+ if len(sys.argv) == 2:
+ adb_cmd = sys.argv[1]
+ else:
+ adb_cmd = 'adb'
+
+ install_gaia()
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,34 @@
+#! /usr/bin/env sh
+APP_DIR=./apps
+APP_DIR_LEN=`expr $APP_DIR : '.*'`
+APP_WEBAPPS=$APP_DIR/webapps.json
+APP_DESKTOP_CACHE=$APP_DIR/homescreen/apps-manifest-fallback.json
+
+## Truncate
+cat < /dev/null > $APP_DESKTOP_CACHE
+
+echo "Creating Desktop App Manifest Shim ($APP_DESKTOP_CACHE)"
+
+echo "{\"webapps\": \n $(cat $APP_WEBAPPS), \"manifests\": { \n" >> $APP_DESKTOP_CACHE
+
+APP_ARR_LEN=0
+APP_MANIFEST_ARR=();
+
+for APP_LOC in `find $APP_DIR -type d -depth 1`
+do
+ APP_NAME=${APP_LOC:(($APP_DIR_LEN+1))}
+ APP_MANIFEST_FILE=$APP_LOC/manifest.json
+ if [ -f $APP_MANIFEST_FILE ];
+ then
+ APP_MANIFEST_ARR[$APP_ARR_LEN]="\"$APP_NAME\": $(cat $APP_MANIFEST_FILE)"
+ APP_ARR_LEN=$(($APP_ARR_LEN+1))
+ fi
+done
+
+SAVE_IFS=$IFS
+IFS=","
+echo "${APP_MANIFEST_ARR[*]}" >> $APP_DESKTOP_CACHE
+echo "}}" >> $APP_DESKTOP_CACHE
+IFS=$SAVE_IFS
+
+echo "Done"
View
103 webapi.js
@@ -1104,6 +1104,109 @@
};
})(this);
+// navigator.mozApps.mgmt
+(function(window){
+
+ if('mozApps' in navigator){
+ return;
+ }
+
+ if(console.log){
+ console.log("Your browser does not have navigator.mozApps using fallback method - run make desktop-fallback-manifest (from gaia)")
+ }
+
+ var MockApp = function(data){
+ var key;
+ for(key in data){
+ this[key] = data[key];
+ }
+
+ };
+
+ MockApp.prototype = {
+
+ getDetails: function() {
+ return {
+ origin: this.origin,
+ url: this.origin + this.manifest.launch_path,
+ type: 'webapps-launch'
+ };
+ },
+
+ launch: function(){
+ var event = document.createEvent('CustomEvent');
+ event.initCustomEvent('mozChromeEvent', true, true, this.getDetails());
+
+ window.dispatchEvent(event);
+ }
+ };
+
+ function MozAppGetAll(){
+ setTimeout(this._loadManifest.bind(this), 0);
+ }
+
+ MozAppGetAll.prototype = {
+
+ //relative to homescreen
+ appManifestFallback: './apps-manifest-fallback.json',
+
+ onsuccess: function(){},
+ onerror: function(){},
+
+ _processAllAppsManifest: function(xhr){
+ var data = JSON.parse(xhr.responseText),
+ app, entry, applications = [];
+
+ for(app in data.webapps){
+ entry = data.webapps[app];
+ entry.manifest = data.manifests[app];
+
+ applications.push(new MockApp(entry));
+ }
+
+ return {
+ target: {
+ result: applications
+ }
+ }
+ },
+
+ _loadManifest: function(){
+ var xhr = new XMLHttpRequest(),
+ self = this;
+
+ xhr.open('GET', this.appManifestFallback, true);
+
+ xhr.onreadystatechange = function() {
+ if(xhr.readyState === 4){
+ if(xhr.status === 200 || xhr.status === 0){
+ self.onsuccess(self._processAllAppsManifest(xhr));
+ } else {
+ //notify user that app fallback failed
+ self.onerror();
+ }
+ }
+ }
+
+ xhr.send(null);
+ }
+ };
+
+ window.navigator.mozApps = {
+ mgmt: {
+ ////stubs
+ oninstall: function(){},
+ onuninstall: function(){},
+
+ getAll: function(){
+ return new MozAppGetAll();
+ }
+ }
+ };
+
+}(this));
+
+
// document.mozL10n
(function(window) {
var gL10nData = {};

0 comments on commit 2c3b925

Please sign in to comment.