Merge m-c to inbound.

This commit is contained in:
Ryan VanderMeulen 2013-05-15 21:17:10 -04:00
commit 4d351a9351
49 changed files with 1640 additions and 251 deletions

View File

@ -1,17 +0,0 @@
#ifndef BOOTANIMATION_H
#define BOOTANIMATION_H
namespace android {
class FramebufferNativeWindow;
}
/* This returns a FramebufferNativeWindow if one exists.
* If not, one is created and the boot animation is started. */
__attribute__ ((weak))
android::FramebufferNativeWindow* NativeWindow();
/* This stops the boot animation if it's still running. */
__attribute__ ((weak))
void StopBootAnimation();
#endif /* BOOTANIMATION_H */

View File

@ -22,17 +22,24 @@ ifndef LIBXUL_SDK
CPPSRCS = nsBrowserApp.cpp
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
CPPSRCS += BootAnimation.cpp
LIBS += \
-lui \
-lEGL \
-lhardware_legacy \
-lhardware \
-lcutils \
$(DEPTH)/media/libpng/$(LIB_PREFIX)mozpng.$(LIB_SUFFIX) \
$(DEPTH)/widget/gonk/libdisplay/$(LIB_PREFIX)display.$(LIB_SUFFIX) \
$(MOZ_ZLIB_LIBS) \
$(NULL)
ifeq (17,$(ANDROID_VERSION))
LIBS += \
-lgui \
-lsuspend \
$(NULL)
endif
OS_LDFLAGS += -Wl,--export-dynamic
LOCAL_INCLUDES += -I$(ANDROID_SOURCE)/hardware/libhardware_legacy/include
LOCAL_INCLUDES += -I$(topsrcdir)/widget/gonk/libdisplay
endif
LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre

View File

@ -30,7 +30,7 @@
#endif
#ifdef MOZ_WIDGET_GONK
#include "BootAnimation.h"
#include "GonkDisplay.h"
#endif
#include "BinaryPath.h"
@ -150,7 +150,7 @@ static int do_main(int argc, char* argv[])
#ifdef MOZ_WIDGET_GONK
/* Called to start the boot animation */
(void) NativeWindow();
(void) mozilla::GetGonkDisplay();
#endif
if (appini) {

View File

@ -73,7 +73,7 @@ VIAddVersionKey "OriginalFilename" "setup.exe"
!insertmacro AddDisabledDDEHandlerValues
!insertmacro ChangeMUIHeaderImage
!insertmacro CheckForFilesInUse
!insertmacro CleanUpdatesDir
!insertmacro CleanUpdateDirectories
!insertmacro CopyFilesFromDir
!insertmacro CreateRegKey
!insertmacro GetLongPath
@ -207,8 +207,11 @@ Section "-InstallStartCleanup"
ClearErrors
${EndIf}
; setup the application model id registration value
${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs"
; Remove the updates directory for Vista and above
${CleanUpdatesDir} "Mozilla\Firefox"
${CleanUpdateDirectories} "Mozilla\Firefox" "Mozilla\updates"
${RemoveDeprecatedFiles}
@ -306,9 +309,6 @@ Section "-Application" APP_IDX
${EndIf}
${EndIf}
; setup the application model id registration value
${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs"
!ifdef MOZ_METRO
${ResetWin8MetroSplash}
!endif

View File

@ -61,6 +61,7 @@ VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
VIAddVersionKey "OriginalFilename" "helper.exe"
!insertmacro AddDisabledDDEHandlerValues
!insertmacro CleanUpdateDirectories
!insertmacro CleanVirtualStore
!insertmacro ElevateUAC
!insertmacro GetLongPath
@ -89,7 +90,7 @@ VIAddVersionKey "OriginalFilename" "helper.exe"
!insertmacro un.ChangeMUIHeaderImage
!insertmacro un.CheckForFilesInUse
!insertmacro un.CleanUpdatesDir
!insertmacro un.CleanUpdateDirectories
!insertmacro un.CleanVirtualStore
!insertmacro un.DeleteRelativeProfiles
!insertmacro un.DeleteShortcuts
@ -271,6 +272,9 @@ Section "Uninstall"
ApplicationID::UninstallJumpLists "$AppUserModelID"
${EndIf}
; Remove the updates directory for Vista and above
${un.CleanUpdateDirectories} "Mozilla\Firefox" "Mozilla\updates"
; Remove any app model id's stored in the registry for this install path
DeleteRegValue HKCU "Software\Mozilla\${AppName}\TaskBarIDs" "$INSTDIR"
DeleteRegValue HKLM "Software\Mozilla\${AppName}\TaskBarIDs" "$INSTDIR"
@ -398,9 +402,6 @@ Section "Uninstall"
Delete /REBOOTOK "$INSTDIR\removed-files"
${EndIf}
; Remove the updates directory for Vista and above
${un.CleanUpdatesDir} "Mozilla\Firefox"
; Remove files that may be left behind by the application in the
; VirtualStore directory.
${un.CleanVirtualStore}

View File

@ -36,9 +36,8 @@ function debug(aMsg) {
function enableOfflineCacheForApp(origin, appId) {
let originURI = Services.io.newURI(origin, null, null);
let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(
originURI, appId, false);
origin, appId, false);
Services.perms.addFromPrincipal(principal, 'offline-app',
Ci.nsIPermissionManager.ALLOW_ACTION);
// Prevent cache from being evicted:
@ -67,7 +66,6 @@ function storeCache(applicationCache, url, file, itemType) {
bufferedOutputStream.writeFrom(inputStream, inputStream.available());
bufferedOutputStream.flush();
bufferedOutputStream.close();
outputStream.close();
inputStream.close();
cacheEntry.markValid();
@ -101,18 +99,15 @@ function readFile(aFile, aCallback) {
}
function parseCacheLine(app, urls, line) {
// Prepend webapp origin in case of absolute path
if (line[0] == '/') {
urls.push(app.origin + line.substring(1));
// Just pass along the url, if we have one
} else if (line.substr(0, 4) == 'http') {
urls.push(line);
} else {
throw new Error('Only accept absolute path and http/https URLs');
try {
let url = Services.io.newURI(line, null, app.origin);
urls.push(url.spec);
} catch(e) {
throw new Error('Unable to parse cache line: ' + line + '(' + e + ')');
}
}
function parseFallbackLine(app, namespaces, fallbacks, line) {
function parseFallbackLine(app, urls, namespaces, fallbacks, line) {
let split = line.split(/[ \t]+/);
if (split.length != 2) {
throw new Error('Should be made of two URLs seperated with spaces')
@ -121,13 +116,16 @@ function parseFallbackLine(app, namespaces, fallbacks, line) {
let [ namespace, fallback ] = split;
// Prepend webapp origin in case of absolute path
if (namespace[0] == '/')
namespace = app.origin + namespace.substring(1);
if (fallback[0] == '/')
fallback = app.origin + fallback.substring(1);
try {
namespace = Services.io.newURI(namespace, null, app.origin).spec;
fallback = Services.io.newURI(fallback, null, app.origin).spec;
} catch(e) {
throw new Error('Unable to parse fallback line: ' + line + '(' + e + ')');
}
namespaces.push([type, namespace, fallback]);
fallbacks.push(fallback);
urls.push(fallback);
}
function parseNetworkLine(namespaces, line) {
@ -176,7 +174,7 @@ function parseAppCache(app, path, content) {
} else if (currentSection == 'NETWORK') {
parseNetworkLine(namespaces, line);
} else if (currentSection == 'FALLBACK') {
parseFallbackLine(app, namespaces, fallbacks, line);
parseFallbackLine(app, urls, namespaces, fallbacks, line);
}
} catch(e) {
throw new Error('Invalid ' + currentSection + ' line in appcache ' +
@ -194,7 +192,11 @@ function parseAppCache(app, path, content) {
}
function installCache(app) {
let cacheDir = makeFile(app.basePath)
if (!app.cachePath) {
return;
}
let cacheDir = makeFile(app.cachePath)
cacheDir.append(app.appId);
cacheDir.append('cache');
if (!cacheDir.exists())
@ -208,7 +210,7 @@ function installCache(app) {
enableOfflineCacheForApp(app.origin, app.localId);
// Get the url for the manifest.
let appcacheURL = app.origin + 'cache/manifest.appcache';
let appcacheURL = app.appcache_path;
// The group ID contains application id and 'f' for not being hosted in
// a browser element, but a mozbrowser iframe.
@ -222,7 +224,9 @@ function installCache(app) {
entries.urls.forEach(function processCachedFile(url) {
// Get this nsIFile from cache folder for this URL
let path = url.replace(/https?:\/\//, '');
// We have absolute urls, so remove the origin part to locate the
// files.
let path = url.replace(app.origin.spec, '');
let file = cacheDir.clone();
let paths = path.split('/');
paths.forEach(file.append);

View File

@ -263,11 +263,15 @@ this.DOMApplicationRegistry = {
updateOfflineCacheForApp: function updateOfflineCacheForApp(aId) {
let app = this.webapps[aId];
OfflineCacheInstaller.installCache({
basePath: app.basePath,
appId: aId,
origin: app.origin,
localId: app.localId
this._readManifests([{ id: aId }], function(aResult) {
let manifest = new ManifestHelper(aResult[0].manifest, app.origin);
OfflineCacheInstaller.installCache({
cachePath: app.cachePath,
appId: aId,
origin: Services.io.newURI(app.origin, null, null),
localId: app.localId,
appcache_path: manifest.fullAppcachePath()
});
});
},
@ -320,6 +324,7 @@ this.DOMApplicationRegistry = {
});
app.installState = "installed";
app.cachePath = app.basePath;
app.basePath = FileUtils.getDir(DIRECTORY_NAME, ["webapps"], true, true)
.path;

View File

@ -259,6 +259,10 @@ NetworkManager.prototype = {
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL) {
this.removeHostRoute(network);
}
// Remove routing table in /proc/net/route
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
this.resetRoutingTable(this._activeInfo);
}
// Abort ongoing captive portal detection on the wifi interface
CaptivePortalDetectionHelper.notify(CaptivePortalDetectionHelper.EVENT_DISCONNECT, network);
this.setAndConfigureActive();
@ -354,6 +358,9 @@ NetworkManager.prototype = {
active: null,
_overriddenActive: null,
// Clone network info so we can still get information when network is disconnected
_activeInfo: null,
overrideActive: function overrideActive(network) {
this._overriddenActive = network;
this.setAndConfigureActive();
@ -442,6 +449,7 @@ NetworkManager.prototype = {
// Find a suitable network interface to activate.
this.active = null;
this._activeInfo = Object.create(null);
for each (let network in this.networkInterfaces) {
if (network.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
continue;
@ -450,6 +458,7 @@ NetworkManager.prototype = {
defaultDataNetwork = network;
}
this.active = network;
this._activeInfo = {name:network.name, ip:network.ip, netmask:network.netmask};
if (network.type == this.preferredNetworkType) {
debug("Found our preferred type of network: " + network.name);
break;
@ -476,6 +485,16 @@ NetworkManager.prototype = {
}
},
resetRoutingTable: function resetRoutingTable(network) {
let options = {
cmd: "removeNetworkRoute",
ifname: network.name,
ip : network.ip,
netmask: network.netmask,
};
this.worker.postMessage(options);
},
setDefaultRouteAndDNS: function setDefaultRouteAndDNS(oldInterface) {
debug("Going to change route and DNS to " + this.active.name);
let options = {

View File

@ -245,6 +245,18 @@ function removeHostRoute(options) {
libnetutils.ifc_remove_route(options.ifname, options.mmsproxy, 32, options.gateway);
}
function removeNetworkRoute(options) {
let ipvalue = netHelpers.stringToIP(options.ip);
let netmaskvalue = netHelpers.stringToIP(options.netmask);
let subnet = netmaskvalue & ipvalue;
let dst = netHelpers.ipToString(subnet);
let prefixLength = netHelpers.getMaskLength(netmaskvalue);
let gateway = "0.0.0.0";
libnetutils.ifc_remove_default_route(options.ifname);
libnetutils.ifc_remove_route(options.ifname, dst, prefixLength, gateway);
}
let gCommandQueue = [];
let gCurrentCommand = null;
let gCurrentCallback = null;

View File

@ -404,5 +404,18 @@ this.netHelpers = {
mask |= (0x80000000 >> i);
}
return this.ntohl(mask);
},
/**
* Get Mask length from given mask address
*/
getMaskLength: function getMaskLength(mask) {
let len = 0;
let netmask = this.ntohl(mask);
while (netmask & 0x80000000) {
len++;
netmask = netmask << 1;
}
return len;
}
};

View File

@ -747,6 +747,10 @@ var WifiManager = (function() {
}
manager.connectionDropped = function(callback) {
// Reset network interface when connection drop
configureInterface(manager.ifname, 0, 0, 0, 0, 0, function (data) {
});
// If we got disconnected, kill the DHCP client in preparation for
// reconnection.
resetConnections(manager.ifname, function() {

View File

@ -20,6 +20,7 @@
#elif defined(MOZ_WIDGET_GONK)
#define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
#include "HwcComposer2D.h"
#include "libdisplay/GonkDisplay.h"
#endif
#if defined(MOZ_X11)
@ -273,7 +274,7 @@ public:
#ifdef DEBUG
printf_stderr("Initializing context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
#endif
#ifdef MOZ_WIDGET_GONK
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION <= 15
if (!mIsOffscreen) {
mHwc = HwcComposer2D::GetInstance();
MOZ_ASSERT(!mHwc->Initialized());
@ -593,9 +594,8 @@ public:
{
if (mSurface && !mPlatformContext) {
#ifdef MOZ_WIDGET_GONK
if (mHwc)
return !mHwc->swapBuffers((hwc_display_t)EGL_DISPLAY(),
(hwc_surface_t)mSurface);
if (!mIsOffscreen)
return GetGonkDisplay()->SwapBuffers(EGL_DISPLAY(), mSurface);
else
#endif
return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), mSurface);
@ -1593,6 +1593,9 @@ static const EGLint kEGLConfigAttribsRGBA32[] = {
LOCAL_EGL_GREEN_SIZE, 8,
LOCAL_EGL_BLUE_SIZE, 8,
LOCAL_EGL_ALPHA_SIZE, 8,
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
LOCAL_EGL_FRAMEBUFFER_TARGET_ANDROID, LOCAL_EGL_TRUE,
#endif
LOCAL_EGL_NONE
};

View File

@ -3323,4 +3323,7 @@ typedef uint64_t EGLTime;
// FAKE_EGL_image_android
#define LOCAL_EGL_NATIVE_BUFFER_ANDROID 0x3140
// EGL_ANDROID_framebuffer_target
#define LOCAL_EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147
#endif

View File

@ -34,6 +34,7 @@
#include "hardware_legacy/uevent.h"
#include "hardware_legacy/vibrator.h"
#include "hardware_legacy/power.h"
#include "libdisplay/GonkDisplay.h"
#include "base/message_loop.h"
@ -513,7 +514,7 @@ GetScreenEnabled()
void
SetScreenEnabled(bool enabled)
{
set_screen_state(enabled);
GetGonkDisplay()->SetEnabled(enabled);
sScreenEnabled = enabled;
}

View File

@ -0,0 +1,30 @@
function _mach()
{
local cur cmds c subcommand mach
COMPREPLY=()
# Load the list of commands
mach=`which mach || echo ./mach`
cmds=`$mach mach-commands`
# Look for the subcommand.
cur="${COMP_WORDS[COMP_CWORD]}"
subcommand=""
c=1
while [ $c -lt $COMP_CWORD ]; do
word="${COMP_WORDS[c]}"
for cmd in $cmds; do
if [ "$cmd" = "$word" ]; then
subcommand="$word"
fi
done
c=$((++c))
done
if [[ "$subcommand" == "help" || -z "$subcommand" ]]; then
COMPREPLY=( $(compgen -W "$cmds" -- ${cur}) )
fi
return 0
}
complete -o default -F _mach mach

View File

@ -15,9 +15,14 @@ class BuiltinCommands(object):
def __init__(self, context):
self.context = context
@Command('mach-commands', category='misc',
description='List all mach commands.')
def commands(self):
print("\n".join(self.context.commands.command_handlers.keys()))
@Command('mach-debug-commands', category='misc',
description='Show info about available mach commands.')
def commands(self):
def debug_commands(self):
import inspect
handlers = self.context.commands.command_handlers

View File

@ -78,7 +78,7 @@ class CommandAction(argparse.Action):
if not values:
raise NoCommandError()
command = values[0]
command = values[0].lower()
args = values[1:]
if command == 'help':

View File

@ -3224,6 +3224,8 @@
/**
* If present removes the updates directory located in the profile's local
* directory for this installation.
* This macro is obsolete and should no longer be used. Please see
* CleanUpdateDirectories.
*
* @param _REL_PROFILE_PATH
* The relative path to the profile directory from $LOCALAPPDATA.
@ -3330,6 +3332,171 @@
!endif
!macroend
/**
* If present removes the updates directory located in the profile's local
* directory for this installation.
*
* @param _OLD_REL_PATH
* The relative path to the profile directory from $LOCALAPPDATA.
* Calculated for the old update directory not based on a hash.
* @param _NEW_REL_PATH
* The relative path to the profile directory from $LOCALAPPDATA.
* Calculated for the new update directory based on a hash.
*
* $R8 = _NEW_REL_PATH
* $R7 = _OLD_REL_PATH
* $R1 = taskBar ID hash located in registry at SOFTWARE\_OLD_REL_PATH\TaskBarIDs
* $R2 = various path values.
* $R3 = length of the long path to $PROGRAMFILES
* $R4 = length of the long path to $INSTDIR
* $R5 = long path to $PROGRAMFILES
* $R6 = long path to $INSTDIR
* $R0 = path to the new update directory built from _NEW_REL_PATH and
* the taskbar ID.
*/
!macro CleanUpdateDirectories
!ifndef ${_MOZFUNC_UN}CleanUpdateDirectories
!define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
!insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
!undef _MOZFUNC_UN
!define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
!undef _MOZFUNC_UN_TMP
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define ${_MOZFUNC_UN}CleanUpdateDirectories "!insertmacro ${_MOZFUNC_UN}CleanUpdateDirectoriesCall"
Function ${_MOZFUNC_UN}CleanUpdateDirectories
Exch $R8
Exch 1
Exch $R7
Push $R6
Push $R5
Push $R4
Push $R3
Push $R2
Push $R1
Push $R0
${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R6
StrLen $R4 "$R6"
${${_MOZFUNC_UN}GetLongPath} "$PROGRAMFILES" $R5
StrLen $R3 "$R5"
${If} $R7 != "" ; _OLD_REL_PATH was passed
${AndIf} $R6 != "" ; We have the install dir path
${AndIf} $R5 != "" ; We the program files path
${AndIf} $R4 > $R3 ; The length of $INSTDIR > the length of $PROGRAMFILES
; Copy from the start of $INSTDIR the length of $PROGRAMFILES
StrCpy $R2 "$R6" $R3
; Check if $INSTDIR is under $PROGRAMFILES
${If} $R2 == $R5
; Copy the relative path to $INSTDIR from $PROGRAMFILES
StrCpy $R2 "$R6" "" $R3
; Concatenate the path $LOCALAPPDATA to the relative profile path and
; the relative path to $INSTDIR from $PROGRAMFILES
StrCpy $R2 "$LOCALAPPDATA\$R7$R2"
${${_MOZFUNC_UN}GetLongPath} "$R2" $R2
${If} $R2 != ""
; Backup the old update directory logs and delete the directory
${If} ${FileExists} "$R2\updates\last-update.log"
Rename "$R2\updates\last-update.log" "$TEMP\moz-update-old-last-update.log"
${EndIf}
${If} ${FileExists} "$R2\updates\backup-update.log"
Rename "$R2\updates\backup-update.log" "$TEMP\moz-update-old-backup-update.log"
${EndIf}
${If} ${FileExists} "$R2\updates"
RmDir /r "$R2"
${EndIf}
${EndIf}
; Get the taskbar ID hash for this installation path
ReadRegStr $R1 HKLM "SOFTWARE\$R7\TaskBarIDs" $R6
${If} $R1 == ""
ReadRegStr $R1 HKCU "SOFTWARE\$R7\TaskBarIDs" $R6
${EndIf}
; If the taskbar ID hash exists then delete the new update directory
; Backup its logs before deleting it.
${If} $R1 != ""
StrCpy $R0 "$LOCALAPPDATA\$R8\$R1"
${If} ${FileExists} "$R0\updates\last-update.log"
Rename "$R0\updates\last-update.log" "$TEMP\moz-update-new-last-update.log"
${EndIf}
${If} ${FileExists} "$R0\updates\backup-update.log"
Rename "$R0\updates\backup-update.log" "$TEMP\moz-update-new-backup-update.log"
${EndIf}
; Remove the old updates directory
${If} ${FileExists} "$R0\updates"
RmDir /r "$R0"
${EndIf}
${EndIf}
${EndIf}
${EndIf}
ClearErrors
Pop $R0
Pop $R1
Pop $R2
Pop $R3
Pop $R4
Pop $R5
Pop $R6
Exch $R7
Exch 1
Exch $R8
FunctionEnd
!verbose pop
!endif
!macroend
!macro CleanUpdateDirectoriesCall _OLD_REL_PATH _NEW_REL_PATH
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_OLD_REL_PATH}"
Push "${_NEW_REL_PATH}"
Call CleanUpdateDirectories
!verbose pop
!macroend
!macro un.CleanUpdateDirectoriesCall _OLD_REL_PATH _NEW_REL_PATH
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_OLD_REL_PATH}"
Push "${_NEW_REL_PATH}"
Call un.CleanUpdateDirectories
!verbose pop
!macroend
!macro un.CleanUpdateDirectories
!ifndef un.CleanUpdateDirectories
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!undef _MOZFUNC_UN
!define _MOZFUNC_UN "un."
!insertmacro CleanUpdateDirectories
!undef _MOZFUNC_UN
!define _MOZFUNC_UN
!verbose pop
!endif
!macroend
/**
* Deletes all relative profiles specified in an application's profiles.ini and
* performs various other cleanup.

View File

@ -18,11 +18,11 @@ ifdef MOZ_UPDATER
EXTRA_PP_COMPONENTS += \
nsUpdateService.js \
nsUpdateServiceStub.js \
$(NULL)
EXTRA_COMPONENTS += \
nsUpdateService.manifest \
nsUpdateServiceStub.js \
$(NULL)
endif

View File

@ -3,16 +3,137 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");
const Ci = Components.interfaces;
const Cc = Components.classes;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const DIR_UPDATES = "updates";
const FILE_UPDATES_DB = "updates.xml";
const FILE_UPDATE_ACTIVE = "active-update.xml";
const FILE_LAST_LOG = "last-update.log";
const FILE_BACKUP_LOG = "backup-update.log";
const FILE_UPDATE_STATUS = "update.status";
const KEY_UPDROOT = "UpdRootD";
#ifdef XP_WIN
const PREF_APP_UPDATE_MIGRATE_APP_DIR = "app.update.migrated.updateDir";
function getTaskbarIDHash(rootKey, exePath, appInfoName) {
let registry = Cc["@mozilla.org/windows-registry-key;1"].
createInstance(Ci.nsIWindowsRegKey);
try {
registry.open(rootKey, "Software\\Mozilla\\" + appInfoName + "\\TaskBarIDs",
Ci.nsIWindowsRegKey.ACCESS_READ);
if (registry.hasValue(exePath)) {
return registry.readStringValue(exePath);
}
} catch (ex) {
} finally {
registry.close();
}
return undefined;
};
/*
* Migrates old update directory files to the new update directory
* which is based on a hash of the installation.
*/
function migrateOldUpdateDir() {
// Get the old udpate root leaf dir. It is based on the sub directory of
// program files, or if the exe path is not inside program files, the appname.
var appinfo = Components.classes["@mozilla.org/xre/app-info;1"].
getService(Components.interfaces.nsIXULAppInfo).
QueryInterface(Components.interfaces.nsIXULRuntime);
var updateLeafName;
var programFiles = FileUtils.getFile("ProgF", []);
var exeFile = FileUtils.getFile("XREExeF", []);
if (exeFile.path.substring(0, programFiles.path.length).toLowerCase() ==
programFiles.path.toLowerCase()) {
updateLeafName = exeFile.parent.leafName;
} else {
updateLeafName = appinfo.name;
}
// Get the old update root dir
var oldUpdateRoot;
if (appinfo.vendor) {
oldUpdateRoot = FileUtils.getDir("LocalAppData", [appinfo.vendor,
appinfo.name,
updateLeafName], false);
} else {
oldUpdateRoot = FileUtils.getDir("LocalAppData", [appinfo.name,
updateLeafName], false);
}
// Obtain the new update root
var newUpdateRoot = FileUtils.getDir("UpdRootD", [], true);
// If there is no taskbar ID then we want to retry this migration
// at a later time if the application gets a taskbar ID.
var taskbarID = getTaskbarIDHash(Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE,
exeFile.parent.path, appinfo.name);
if (!taskbarID) {
taskbarID = getTaskbarIDHash(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
exeFile.parent.path, appinfo.name);
if (!taskbarID) {
return;
}
}
Services.prefs.setBoolPref(PREF_APP_UPDATE_MIGRATE_APP_DIR, true);
// Sanity checks only to ensure we don't delete something we don't mean to.
if (oldUpdateRoot.path.toLowerCase() == newUpdateRoot.path.toLowerCase() ||
updateLeafName.length == 0) {
return;
}
// If the old update root doesn't exist then we have already migrated
// or else there is no work to do.
if (!oldUpdateRoot.exists()) {
return;
}
// Get an array of all of the files we want to migrate.
// We do this so we don't copy anything extra.
var filesToMigrate = [FILE_UPDATES_DB, FILE_UPDATE_ACTIVE,
["updates", FILE_LAST_LOG], ["updates", FILE_BACKUP_LOG],
["updates", "0", FILE_UPDATE_STATUS]];
// Move each of those files to the new directory
filesToMigrate.forEach(relPath => {
let oldFile = oldUpdateRoot.clone();
let newFile = newUpdateRoot.clone();
if (relPath instanceof Array) {
relPath.forEach(relPathPart => {
oldFile.append(relPathPart);
newFile.append(relPathPart);
});
} else {
oldFile.append(relPath);
newFile.append(relPath);
}
try {
if (!newFile.exists()) {
oldFile.moveTo(newFile.parent, newFile.leafName);
}
} catch (e) {
Components.utils.reportError(e);
}
});
oldUpdateRoot.remove(true);
}
#endif
/**
* Gets the specified directory at the specified hierarchy under the update root
* directory without creating it if it doesn't exist.
@ -26,6 +147,23 @@ function getUpdateDirNoCreate(pathArray) {
}
function UpdateServiceStub() {
#ifdef XP_WIN
// Don't attempt this migration more than once for perf reasons
var migrated = 0;
try {
migrated = Services.prefs.getBoolPref(PREF_APP_UPDATE_MIGRATE_APP_DIR);
} catch (e) {
}
if (!migrated) {
try {
migrateOldUpdateDir();
} catch (e) {
Components.utils.reportError(e);
}
}
#endif
let statusFile = getUpdateDirNoCreate([DIR_UPDATES, "0"]);
statusFile.append(FILE_UPDATE_STATUS);
// If the update.status file exists then initiate post update processing.

View File

@ -6,6 +6,9 @@ const INSTALL_LOCALE = "@AB_CD@";
const APP_BIN_NAME = "@MOZ_APP_NAME@";
const BIN_SUFFIX = "@BIN_SUFFIX@";
const APP_INFO_NAME = "XPCShell";
const APP_INFO_VENDOR = "Mozilla";
#ifdef XP_UNIX
const APP_BIN_SUFFIX = "-bin";
#else
@ -367,7 +370,7 @@ function setDefaultPrefs() {
* update service stub.
*/
function standardInit() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1.0", "2.0");
createAppInfo("xpcshell@tests.mozilla.org", APP_INFO_NAME, "1.0", "2.0");
setDefaultPrefs();
// Initialize the update service stub component
initUpdateServiceStub();
@ -926,6 +929,7 @@ function runUpdateUsingService(aInitialStatus, aExpectedStatus,
// Override the update root directory
gEnvUpdateRootOverride = updatesDir.path;
gEnvAppDirOverride = getApplyDirFile(null).path;
gEnvSKipUpdateDirHashing = true;
if (gSwitchApp) {
// We want to set the env vars again
@ -1857,7 +1861,7 @@ function createAppInfo(id, name, version, platformVersion) {
const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1";
const XULAPPINFO_CID = Components.ID("{c763b610-9d49-455a-bbd2-ede71682a1ac}");
var XULAppInfo = {
vendor: "Mozilla",
vendor: APP_INFO_VENDOR,
name: name,
ID: id,
version: version,
@ -2138,6 +2142,7 @@ let gEnvDyldLibraryPath;
let gEnvLdLibraryPath;
let gEnvUpdateRootOverride = null;
let gEnvAppDirOverride = null;
let gEnvSKipUpdateDirHashing = false;
/**
* Sets the environment that will be used by the application process when it is
@ -2217,6 +2222,10 @@ function setEnvironment() {
env.set("XPCOM_DEBUG_BREAK", "warn");
if (IS_WIN && gEnvSKipUpdateDirHashing) {
env.set("MOZ_UPDATE_NO_HASH_DIR", "1");
}
if (gEnvUpdateRootOverride) {
logTestInfo("setting the MOZ_UPDATE_ROOT_OVERRIDE environment variable to " +
gEnvUpdateRootOverride + "\n");

View File

@ -46,6 +46,7 @@ function run_test() {
return;
}
gEnvSKipUpdateDirHashing = true;
let channel = Services.prefs.getCharPref(PREF_APP_UPDATE_CHANNEL);
let patches = getLocalPatchString(null, null, null, null, null, "true",
STATE_PENDING);

View File

@ -129,6 +129,7 @@ function run_test() {
// Don't attempt to show a prompt when the update is finished.
Services.prefs.setBoolPref(PREF_APP_UPDATE_SILENT, true);
gEnvSKipUpdateDirHashing = true;
let channel = Services.prefs.getCharPref(PREF_APP_UPDATE_CHANNEL);
let patches = getLocalPatchString(null, null, null, null, null, "true",
STATE_PENDING);

View File

@ -137,6 +137,7 @@ function run_test() {
// Don't attempt to show a prompt when the update is finished.
Services.prefs.setBoolPref(PREF_APP_UPDATE_SILENT, true);
gEnvSKipUpdateDirHashing = true;
let channel = Services.prefs.getCharPref(PREF_APP_UPDATE_CHANNEL);
let patches = getLocalPatchString(null, null, null, null, null, "true",
STATE_PENDING);

View File

@ -0,0 +1,178 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
const TEST_ID = "0300";
const PREF_APP_UPDATE_MIGRATE_APP_DIR = "app.update.migrated.updateDir";
// Maximum number of milliseconds the process that is launched can run before
// the test will try to kill it.
const APP_TIMER_TIMEOUT = 120000;
Components.utils.import("resource://gre/modules/FileUtils.jsm");
function clearTaskbarIDHash(exePath, appInfoName) {
let registry = AUS_Cc["@mozilla.org/windows-registry-key;1"].
createInstance(AUS_Ci.nsIWindowsRegKey);
try {
registry.open(AUS_Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
"Software\\Mozilla\\" + appInfoName + "\\TaskBarIDs",
AUS_Ci.nsIWindowsRegKey.ACCESS_ALL);
registry.removeValue(exePath);
} catch (ex) {
} finally {
registry.close();
}
}
function setTaskbarIDHash(exePath, hash, appInfoName) {
let registry = AUS_Cc["@mozilla.org/windows-registry-key;1"].
createInstance(AUS_Ci.nsIWindowsRegKey);
try {
registry.create(AUS_Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
"Software\\Mozilla\\" + appInfoName + "\\TaskBarIDs",
AUS_Ci.nsIWindowsRegKey.ACCESS_WRITE);
registry.writeStringValue(exePath, hash);
} catch (ex) {
} finally {
registry.close();
}
};
function getMigrated() {
var migrated = 0;
try {
migrated = Services.prefs.getBoolPref(PREF_APP_UPDATE_MIGRATE_APP_DIR);
} catch (e) {
}
return migrated;
}
/* General Update Manager Tests */
function run_test() {
do_test_pending();
do_register_cleanup(end_test);
standardInit();
var appinfo = Components.classes["@mozilla.org/xre/app-info;1"].
getService(Components.interfaces.nsIXULAppInfo).
QueryInterface(Components.interfaces.nsIXULRuntime);
// Obtain the old update root leaf
var exeFile = FileUtils.getFile("XREExeF", []);
var updateLeafName;
var programFiles = FileUtils.getFile("ProgF", []);
var exeFile = FileUtils.getFile("XREExeF", []);
if (exeFile.path.substring(0, programFiles.path.length).toLowerCase() ==
programFiles.path.toLowerCase()) {
updateLeafName = exeFile.parent.leafName;
} else {
updateLeafName = appinfo.name;
}
// Obtain the old update root
var oldUpdateRoot;
if (appinfo.vendor) {
oldUpdateRoot = FileUtils.getDir("LocalAppData", [appinfo.vendor,
appinfo.name,
updateLeafName], false);
} else {
oldUpdateRoot = FileUtils.getDir("LocalAppData", [appinfo.name,
updateLeafName], false);
}
// Obtain the new update root
var newUpdateRoot = FileUtils.getDir("UpdRootD", [], false);
///////////////////////////////////////////////////////////
// Setting a taskbar ID without the old update dir existing should set the
// pref so a migration isn't retried.
// Remove the old and new update root directories
try {
oldUpdateRoot.remove(true);
} catch (e) {
}
try {
newUpdateRoot.remove(true);
} catch (e) {
}
Services.prefs.setBoolPref(PREF_APP_UPDATE_MIGRATE_APP_DIR, false);
setTaskbarIDHash(exeFile.parent.path, "AAAAAAAA", appinfo.name);
initUpdateServiceStub();
do_check_eq(getMigrated(), 1);
///////////////////////////////////////////////////////////
// An application without a taskbar ID should bail early without a pref
// being set, so that if a taskbar is set for the application, the migration
// will be retried.
Services.prefs.setBoolPref(PREF_APP_UPDATE_MIGRATE_APP_DIR, false);
clearTaskbarIDHash(exeFile.parent.path, appinfo.name);
initUpdateServiceStub();
do_check_eq(getMigrated(), 0);
///////////////////////////////////////////////////////////
// Migrating files should work
Services.prefs.setBoolPref(PREF_APP_UPDATE_MIGRATE_APP_DIR, false);
setTaskbarIDHash(exeFile.parent.path, "AAAAAAAA", appinfo.name);
var oldUpdateDirs = oldUpdateRoot.clone();
oldUpdateDirs.append("updates");
oldUpdateDirs.append("0");
oldUpdateDirs.create(AUS_Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
// Get an array of all of the files we want to migrate.
// We do this to create them in the old update directory.
var filesToMigrate = [FILE_UPDATES_DB, FILE_UPDATE_ACTIVE,
["updates", FILE_LAST_LOG], ["updates", FILE_BACKUP_LOG],
["updates", "0", FILE_UPDATE_STATUS]];
// Move each of those files to the new directory
filesToMigrate.forEach(relPath => {
let oldFile = oldUpdateRoot.clone();
if (relPath instanceof Array) {
relPath.forEach(relPathPart => {
oldFile.append(relPathPart);
});
} else {
oldFile.append(relPath);
}
oldFile.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
});
// Do the migration
initUpdateServiceStub();
do_test_finished();
return;
// Now verify that each of the files exist in the new update directory
filesToMigrate.forEach(relPath => {
let newFile = newUpdateRoot.clone();
let oldFile = oldUpdateRoot.clone();
if (relPath instanceof Array) {
relPath.forEach(relPathPart => {
newFile.append(relPathPart);
oldFile.append(relPathPart);
});
} else {
newFile.append(relPath);
oldFile.append(relPath);
}
// The file should be mimgrated, except for FILE_UPDATE_STATUS
// which gets consumed by post update after it is migrated..
if (newFile.leafName != FILE_UPDATE_STATUS) {
do_check_true(newFile.exists());
}
do_check_false(oldFile.exists());
});
do_test_finished();
}
function end_test() {
var appinfo = Components.classes["@mozilla.org/xre/app-info;1"].
getService(Components.interfaces.nsIXULAppInfo).
QueryInterface(Components.interfaces.nsIXULRuntime);
var exeFile = FileUtils.getFile("XREExeF", []);
clearTaskbarIDHash(exeFile.parent.path, appinfo.name);
cleanUp();
}

View File

@ -26,3 +26,4 @@
[test_0191_rmrfdirFileInUse_xp_win_partial.js]
[test_0202_app_launch_apply_update_dirlocked.js]
[test_0203_app_launch_apply_update.js]
[test_0300_update_root_dir_migration.js]

View File

@ -39,6 +39,7 @@ function run_test() {
return;
}
gEnvSKipUpdateDirHashing = true;
let channel = Services.prefs.getCharPref(PREF_APP_UPDATE_CHANNEL);
let patches = getLocalPatchString(null, null, null, null, null, "true",
STATE_PENDING);

View File

@ -128,6 +128,7 @@ function run_test() {
// Don't attempt to show a prompt when the update is finished.
Services.prefs.setBoolPref(PREF_APP_UPDATE_SILENT, true);
gEnvSKipUpdateDirHashing = true;
let channel = Services.prefs.getCharPref(PREF_APP_UPDATE_CHANNEL);
let patches = getLocalPatchString(null, null, null, null, null, "true",
STATE_PENDING_SVC);

View File

@ -136,6 +136,7 @@ function run_test() {
// Don't attempt to show a prompt when the update is finished.
Services.prefs.setBoolPref(PREF_APP_UPDATE_SILENT, true);
gEnvSKipUpdateDirHashing = true;
let channel = Services.prefs.getCharPref(PREF_APP_UPDATE_CHANNEL);
let patches = getLocalPatchString(null, null, null, null, null, "true",
STATE_PENDING_SVC);

View File

@ -954,6 +954,28 @@ GetRegWindowsAppDataFolder(bool aLocal, nsAString& _retval)
return NS_OK;
}
static bool
GetCachedHash(HKEY rootKey, const nsAString &regPath, const nsAString &path,
nsAString &cachedHash)
{
HKEY baseKey;
if (RegOpenKeyExW(rootKey, regPath.BeginReading(), 0, KEY_READ, &baseKey) !=
ERROR_SUCCESS) {
return false;
}
wchar_t cachedHashRaw[512];
DWORD bufferSize = sizeof(cachedHashRaw);
LONG result = RegQueryValueExW(baseKey, path.BeginReading(), 0, NULL,
(LPBYTE)cachedHashRaw, &bufferSize);
RegCloseKey(baseKey);
if (result == ERROR_SUCCESS) {
cachedHash.Assign(cachedHashRaw);
}
return ERROR_SUCCESS == result;
}
#endif
nsresult
@ -976,6 +998,46 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
NS_ENSURE_SUCCESS(rv, rv);
#ifdef XP_WIN
nsAutoString pathHash;
bool pathHashResult = false;
nsAutoString appDirPath;
if (gAppData->vendor && !getenv("MOZ_UPDATE_NO_HASH_DIR") &&
SUCCEEDED(updRoot->GetPath(appDirPath))) {
// Figure out where we should check for a cached hash value
wchar_t regPath[1024] = { L'\0' };
swprintf_s(regPath, mozilla::ArrayLength(regPath), L"SOFTWARE\\%S\\%S\\TaskBarIDs",
gAppData->vendor, MOZ_APP_NAME);
// If we pre-computed the hash, grab it from the registry.
pathHashResult = GetCachedHash(HKEY_LOCAL_MACHINE,
nsDependentString(regPath), appDirPath,
pathHash);
if (!pathHashResult) {
pathHashResult = GetCachedHash(HKEY_CURRENT_USER,
nsDependentString(regPath), appDirPath,
pathHash);
}
}
// Get the local app data directory and if a vendor name exists append it.
// If only a product name exists, append it. If neither exist fallback to
// old handling. We don't use the product name on purpose because we want a
// shared update directory for different apps run from the same path (like
// Metro & Desktop).
nsCOMPtr<nsIFile> localDir;
if (pathHashResult && (gAppData->vendor || gAppData->name) &&
NS_SUCCEEDED(GetUserDataDirectoryHome(getter_AddRefs(localDir), true)) &&
NS_SUCCEEDED(localDir->AppendNative(nsDependentCString(gAppData->vendor ?
gAppData->vendor : gAppData->name))) &&
NS_SUCCEEDED(localDir->Append(NS_LITERAL_STRING("updates"))) &&
NS_SUCCEEDED(localDir->Append(pathHash))) {
NS_ADDREF(*aResult = localDir);
return NS_OK;
}
nsAutoString appPath;
rv = updRoot->GetPath(appPath);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -1,66 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "HWComposer.h"
#include <hardware/hardware.h>
#include <EGL/egl.h>
namespace android {
// ---------------------------------------------------------------------------
HWComposer::HWComposer()
: mModule(0), mHwc(0),
mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
{
}
HWComposer::~HWComposer() {
if (mHwc) {
hwc_close(mHwc);
}
}
int HWComposer::init() {
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
LOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
if (err)
return err;
err = hwc_open(mModule, &mHwc);
LOGE_IF(err, "%s device failed to initialize (%s)",
HWC_HARDWARE_COMPOSER, strerror(-err));
if (err) {
mHwc = NULL;
return err;
}
if (mHwc->registerProcs) {
mCBContext.hwc = this;
mHwc->registerProcs(mHwc, &mCBContext.procs);
}
return 0;
}
status_t HWComposer::swapBuffers(hwc_display_t dpy, hwc_surface_t surf) const {
mHwc->prepare(mHwc, NULL);
int err = mHwc->set(mHwc, dpy, surf, 0);
return (status_t)err;
}
// ---------------------------------------------------------------------------
}; // namespace android

View File

@ -15,7 +15,9 @@
*/
#include <android/log.h>
#include <string.h>
#include "libdisplay/GonkDisplay.h"
#include "Framebuffer.h"
#include "HwcComposer2D.h"
#include "LayerManagerOGL.h"
@ -61,6 +63,7 @@ static StaticRefPtr<HwcComposer2D> sInstance;
HwcComposer2D::HwcComposer2D()
: mMaxLayerCount(0)
, mList(nullptr)
, mHwc(nullptr)
{
}
@ -73,9 +76,10 @@ HwcComposer2D::Init(hwc_display_t dpy, hwc_surface_t sur)
{
MOZ_ASSERT(!Initialized());
if (int err = init()) {
mHwc = (hwc_composer_device_t*)GetGonkDisplay()->GetHWCDevice();
if (!mHwc) {
LOGE("Failed to initialize hwc");
return err;
return -1;
}
nsIntSize screenSize;

View File

@ -18,11 +18,12 @@
#define mozilla_HwcComposer2D
#include "Composer2D.h"
#include "HWComposer.h"
#include "Layers.h"
#include <vector>
#include <list>
#include "hardware/hwcomposer.h"
namespace mozilla {
namespace layers {
@ -34,8 +35,7 @@ class Layer;
//used to decribe the complex visible region of a layer
typedef std::vector<hwc_rect_t> RectVector;
class HwcComposer2D : public android::HWComposer,
public mozilla::layers::Composer2D {
class HwcComposer2D : public mozilla::layers::Composer2D {
public:
HwcComposer2D();
virtual ~HwcComposer2D();
@ -56,7 +56,10 @@ private:
bool PrepareLayerList(layers::Layer* aContainer, const nsIntRect& aClip,
const gfxMatrix& aParentTransform, const gfxMatrix& aGLWorldTransform);
hwc_composer_device_t* mHwc;
hwc_layer_list_t* mList;
hwc_display_t mDpy;
hwc_surface_t mSur;
nsIntRect mScreenRect;
int mMaxLayerCount;
bool mColorFill;

View File

@ -31,8 +31,6 @@ LIBXUL_LIBRARY = 1
CPPSRCS = \
Framebuffer.cpp \
HWComposer.cpp \
HwcComposer2D.cpp \
nsAppShell.cpp \
nsWidgetFactory.cpp \
nsWindow.cpp \
@ -64,6 +62,10 @@ CPPSRCS = \
Static.cpp \
$(NULL)
ifeq (15,$(ANDROID_VERSION))
CPPSRCS += HwcComposer2D.cpp
endif
SHARED_LIBRARY_LIBS = ../xpwidgets/libxpwidgets_s.a
include $(topsrcdir)/config/rules.mk
@ -73,7 +75,6 @@ DEFINES += -D_IMPL_NS_WIDGET -DHAVE_OFF64_T -DSK_BUILD_FOR_ANDROID_NDK
LOCAL_INCLUDES += \
-I$(ANDROID_SOURCE)/hardware/libhardware/include \
-I$(ANDROID_SOURCE)/hardware/libhardware_legacy/include \
-I$(topsrcdir)/b2g/app \
-I$(topsrcdir)/widget/xpwidgets \
-I$(topsrcdir)/widget/shared \
-I$(topsrcdir)/dom/system/android \

View File

@ -26,19 +26,16 @@
#include "png.h"
#include "android/log.h"
#include "ui/FramebufferNativeWindow.h"
#include "hardware_legacy/power.h"
#include "GonkDisplay.h"
#include "hardware/gralloc.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
#define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "Gonk", ## args)
#define LOGE(args...) __android_log_print(ANDROID_LOG_ERROR, "Gonk", ## args)
using namespace android;
using namespace mozilla;
using namespace std;
static sp<FramebufferNativeWindow> gNativeWindow;
static pthread_t sAnimationThread;
static bool sRunAnimation;
@ -260,8 +257,6 @@ struct AnimationPart {
vector<AnimationFrame> frames;
};
using namespace android;
struct RawReadState {
const char *start;
uint32_t offset;
@ -421,9 +416,8 @@ AnimationThread(void *)
return nullptr;
}
int format;
ANativeWindow *window = gNativeWindow.get();
window->query(window, NATIVE_WINDOW_FORMAT, &format);
GonkDisplay *display = GetGonkDisplay();
int format = display->surfaceformat;
hw_module_t const *module;
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module)) {
@ -514,16 +508,11 @@ AnimationThread(void *)
frame.ReadPngFrame(format);
}
ANativeWindowBuffer *buf;
if (window->dequeueBuffer(window, &buf)) {
ANativeWindowBuffer *buf = display->DequeueBuffer();
if (!buf) {
LOGW("Failed to get an ANativeWindowBuffer");
break;
}
if (window->lockBuffer(window, buf)) {
LOGW("Failed to lock ANativeWindowBuffer");
window->queueBuffer(window, buf);
break;
}
void *vaddr;
if (grmodule->lock(grmodule, buf->handle,
@ -532,7 +521,7 @@ AnimationThread(void *)
GRALLOC_USAGE_HW_FB,
0, 0, width, height, &vaddr)) {
LOGW("Failed to lock buffer_handle_t");
window->queueBuffer(window, buf);
display->QueueBuffer(buf);
break;
}
memcpy(vaddr, frame.buf,
@ -546,10 +535,11 @@ AnimationThread(void *)
if (tv2.tv_usec < frameDelayUs) {
usleep(frameDelayUs - tv2.tv_usec);
} else {
LOGW("Frame delay is %d us but decoding took %d us", frameDelayUs, tv2.tv_usec);
LOGW("Frame delay is %d us but decoding took %d us",
frameDelayUs, tv2.tv_usec);
}
window->queueBuffer(window, buf);
display->QueueBuffer(buf);
if (part.count && j >= part.count) {
free(frame.buf);
@ -563,61 +553,14 @@ AnimationThread(void *)
return nullptr;
}
static int
CancelBufferNoop(ANativeWindow* aWindow, android_native_buffer_t* aBuffer)
void
StartBootAnimation()
{
return 0;
}
__attribute__ ((visibility ("default")))
FramebufferNativeWindow*
NativeWindow()
{
if (gNativeWindow.get()) {
return gNativeWindow.get();
}
// Some gralloc HALs need this in order to open the
// framebuffer device after we restart with the screen off.
//
// NB: this *must* run BEFORE allocating the
// FramebufferNativeWindow. Do not separate these two C++
// statements.
set_screen_state(1);
// For some devices, it takes a while for the framebuffer to become
// usable. So we wait until the framebuffer has woken up before we
// try to open it.
{
char buf;
int len = 0;
ScopedClose fd(open("/sys/power/wait_for_fb_wake", O_RDONLY, 0));
do {
len = read(fd.get(), &buf, 1);
} while (len < 0 && errno == EINTR);
if (len < 0) {
LOGE("BootAnimation: wait_for_fb_sleep failed errno: %d", errno);
}
}
// We (apparently) don't have a way to tell if allocating the
// fbs succeeded or failed.
gNativeWindow = new FramebufferNativeWindow();
// Bug 776742: FrambufferNativeWindow doesn't set the cancelBuffer
// function pointer, causing EGL to segfault when the window surface
// is destroyed (i.e. on process exit). This workaround stops us
// from hard crashing in that situation.
gNativeWindow->cancelBuffer = CancelBufferNoop;
sRunAnimation = true;
pthread_create(&sAnimationThread, nullptr, AnimationThread, nullptr);
return gNativeWindow.get();
}
__attribute__ ((visibility ("default")))
void
StopBootAnimation()
{

View File

@ -0,0 +1,24 @@
/* Copyright 2012 Mozilla Foundation and Mozilla contributors
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BOOTANIMATION_H
#define BOOTANIMATION_H
void StartBootAnimation();
/* Stop the boot animation if it's still running. */
void StopBootAnimation();
#endif /* BOOTANIMATION_H */

View File

@ -0,0 +1,160 @@
/*
**
** Copyright 2012 The Android Open Source Project
**
** Licensed under the Apache License Version 2.0(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.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing software
** distributed under the License is distributed on an "AS IS" BASIS
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <cutils/log.h>
#include <utils/String8.h>
#include <ui/Rect.h>
#include <EGL/egl.h>
#include <hardware/hardware.h>
#include <gui/SurfaceTextureClient.h>
#include <ui/GraphicBuffer.h>
#include "FramebufferSurface.h"
#include "GraphicBufferAlloc.h"
#ifndef NUM_FRAMEBUFFER_SURFACE_BUFFERS
#define NUM_FRAMEBUFFER_SURFACE_BUFFERS (2)
#endif
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
/*
* This implements the (main) framebuffer management. This class
* was adapted from the version in SurfaceFlinger
*/
FramebufferSurface::FramebufferSurface(int disp, uint32_t width, uint32_t height, uint32_t format, sp<IGraphicBufferAlloc>& alloc) :
ConsumerBase(new BufferQueue(true, alloc)),
mDisplayType(disp),
mCurrentBufferSlot(-1),
mCurrentBuffer(0)
{
mName = "FramebufferSurface";
mBufferQueue->setConsumerName(mName);
mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
GRALLOC_USAGE_HW_RENDER |
GRALLOC_USAGE_HW_COMPOSER);
mBufferQueue->setDefaultBufferFormat(format);
mBufferQueue->setDefaultBufferSize(width, height);
mBufferQueue->setSynchronousMode(true);
mBufferQueue->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
}
status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
Mutex::Autolock lock(mMutex);
BufferQueue::BufferItem item;
status_t err = acquireBufferLocked(&item);
if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
outBuffer = mCurrentBuffer;
return NO_ERROR;
} else if (err != NO_ERROR) {
ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err);
return err;
}
// If the BufferQueue has freed and reallocated a buffer in mCurrentSlot
// then we may have acquired the slot we already own. If we had released
// our current buffer before we call acquireBuffer then that release call
// would have returned STALE_BUFFER_SLOT, and we would have called
// freeBufferLocked on that slot. Because the buffer slot has already
// been overwritten with the new buffer all we have to do is skip the
// releaseBuffer call and we should be in the same state we'd be in if we
// had released the old buffer first.
if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT &&
item.mBuf != mCurrentBufferSlot) {
// Release the previous buffer.
err = releaseBufferLocked(mCurrentBufferSlot, EGL_NO_DISPLAY,
EGL_NO_SYNC_KHR);
if (err != NO_ERROR && err != BufferQueue::STALE_BUFFER_SLOT) {
ALOGE("error releasing buffer: %s (%d)", strerror(-err), err);
return err;
}
}
mCurrentBufferSlot = item.mBuf;
mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
outFence = item.mFence;
outBuffer = mCurrentBuffer;
return NO_ERROR;
}
// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.
void FramebufferSurface::onFrameAvailable() {
sp<GraphicBuffer> buf;
sp<Fence> acquireFence;
status_t err = nextBuffer(buf, acquireFence);
if (err != NO_ERROR) {
ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)",
strerror(-err), err);
return;
}
if (acquireFence.get())
lastFenceFD = acquireFence->dup();
else
lastFenceFD = -1;
lastHandle = buf->handle;
}
void FramebufferSurface::freeBufferLocked(int slotIndex) {
ConsumerBase::freeBufferLocked(slotIndex);
if (slotIndex == mCurrentBufferSlot) {
mCurrentBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
}
}
status_t FramebufferSurface::setReleaseFenceFd(int fenceFd) {
status_t err = NO_ERROR;
if (fenceFd >= 0) {
sp<Fence> fence(new Fence(fenceFd));
if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
status_t err = addReleaseFence(mCurrentBufferSlot, fence);
ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)",
strerror(-err), err);
}
}
return err;
}
status_t FramebufferSurface::setUpdateRectangle(const Rect& r)
{
return INVALID_OPERATION;
}
status_t FramebufferSurface::compositionComplete()
{
return NO_ERROR;
}
void FramebufferSurface::dump(String8& result) {
ConsumerBase::dump(result);
}
// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------

View File

@ -0,0 +1,84 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_SF_FRAMEBUFFER_SURFACE_H
#define ANDROID_SF_FRAMEBUFFER_SURFACE_H
#include <stdint.h>
#include <sys/types.h>
#include <gui/ConsumerBase.h>
// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------
class Rect;
class String8;
class HWComposer;
// ---------------------------------------------------------------------------
class FramebufferSurface : public ConsumerBase {
public:
FramebufferSurface(int disp, uint32_t width, uint32_t height, uint32_t format, sp<IGraphicBufferAlloc>& alloc);
bool isUpdateOnDemand() const { return false; }
status_t setUpdateRectangle(const Rect& updateRect);
status_t compositionComplete();
virtual void dump(String8& result);
// setReleaseFenceFd stores a fence file descriptor that will signal when the
// current buffer is no longer being read. This fence will be returned to
// the producer when the current buffer is released by updateTexImage().
// Multiple fences can be set for a given buffer; they will be merged into
// a single union fence. The SurfaceTexture will close the file descriptor
// when finished with it.
status_t setReleaseFenceFd(int fenceFd);
buffer_handle_t lastHandle;
int lastFenceFD;
private:
virtual ~FramebufferSurface() { }; // this class cannot be overloaded
virtual void onFrameAvailable();
virtual void freeBufferLocked(int slotIndex);
// nextBuffer waits for and then latches the next buffer from the
// BufferQueue and releases the previously latched buffer to the
// BufferQueue. The new buffer is returned in the 'buffer' argument.
status_t nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence);
// mDisplayType must match one of the HWC display types
int mDisplayType;
// mCurrentBufferIndex is the slot index of the current buffer or
// INVALID_BUFFER_SLOT to indicate that either there is no current buffer
// or the buffer is not associated with a slot.
int mCurrentBufferSlot;
// mCurrentBuffer is the current buffer or NULL to indicate that there is
// no current buffer.
sp<GraphicBuffer> mCurrentBuffer;
};
// ---------------------------------------------------------------------------
}; // namespace android
// ---------------------------------------------------------------------------
#endif // ANDROID_SF_FRAMEBUFFER_SURFACE_H

View File

@ -0,0 +1,48 @@
/* Copyright 2013 Mozilla Foundation and Mozilla contributors
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GONKDISPLAY_H
#define GONKDISPLAY_H
#include <system/window.h>
namespace mozilla {
typedef void * EGLDisplay;
typedef void * EGLSurface;
class GonkDisplay {
public:
virtual ANativeWindow* GetNativeWindow() = 0;
virtual void SetEnabled(bool enabled) = 0;
virtual void* GetHWCDevice() = 0;
virtual bool SwapBuffers(EGLDisplay dpy, EGLSurface sur) = 0;
virtual ANativeWindowBuffer* DequeueBuffer() = 0;
virtual bool QueueBuffer(ANativeWindowBuffer* buf) = 0;
uint32_t xdpi;
uint32_t surfaceformat;
};
__attribute__ ((weak))
GonkDisplay* GetGonkDisplay();
}
#endif /* GONKDISPLAY_H */

View File

@ -0,0 +1,141 @@
/* Copyright 2013 Mozilla Foundation and Mozilla contributors
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "GonkDisplayICS.h"
#include <ui/FramebufferNativeWindow.h>
#include <hardware/hardware.h>
#include <hardware/gralloc.h>
#include <hardware/hwcomposer.h>
#include <hardware_legacy/power.h>
#include <cutils/log.h>
#include <fcntl.h>
#include "mozilla/FileUtils.h"
#include "mozilla/NullPtr.h"
#include "BootAnimation.h"
using namespace android;
namespace mozilla {
static GonkDisplayICS* sGonkDisplay = nullptr;
GonkDisplayICS::GonkDisplayICS()
: mModule(nullptr)
, mHwc(nullptr)
{
// Some gralloc HALs need this in order to open the
// framebuffer device after we restart with the screen off.
//
// this *must* run BEFORE allocating the
// FramebufferNativeWindow.
set_screen_state(1);
// For some devices, it takes a while for the framebuffer to become
// usable. So we wait until the framebuffer has woken up before we
// try to open it.
{
char buf;
int len = 0;
ScopedClose fd(open("/sys/power/wait_for_fb_wake", O_RDONLY, 0));
do {
len = read(fd.get(), &buf, 1);
} while (len < 0 && errno == EINTR);
if (len < 0) {
LOGE("BootAnimation: wait_for_fb_sleep failed errno: %d", errno);
}
}
mFBSurface = new FramebufferNativeWindow();
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
LOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
if (!err) {
err = hwc_open(mModule, &mHwc);
LOGE_IF(err, "%s device failed to initialize (%s)",
HWC_HARDWARE_COMPOSER, strerror(-err));
}
xdpi = mFBSurface->xdpi;
const framebuffer_device_t *fbdev = mFBSurface->getDevice();
surfaceformat = fbdev->format;
StartBootAnimation();
}
GonkDisplayICS::~GonkDisplayICS()
{
if (mHwc)
hwc_close(mHwc);
}
ANativeWindow*
GonkDisplayICS::GetNativeWindow()
{
StopBootAnimation();
return static_cast<ANativeWindow *>(mFBSurface.get());
}
void
GonkDisplayICS::SetEnabled(bool enabled)
{
set_screen_state(enabled);
}
void*
GonkDisplayICS::GetHWCDevice()
{
return mHwc;
}
bool
GonkDisplayICS::SwapBuffers(EGLDisplay dpy, EGLSurface sur)
{
if (!mHwc)
return eglSwapBuffers(dpy, sur);
mHwc->prepare(mHwc, nullptr);
return !mHwc->set(mHwc, dpy, sur, 0);
}
ANativeWindowBuffer*
GonkDisplayICS::DequeueBuffer()
{
ANativeWindow *window = static_cast<ANativeWindow *>(mFBSurface.get());
ANativeWindowBuffer *buf = nullptr;
window->dequeueBuffer(window, &buf);
return buf;
}
bool
GonkDisplayICS::QueueBuffer(ANativeWindowBuffer *buf)
{
ANativeWindow *window = static_cast<ANativeWindow *>(mFBSurface.get());
return !window->queueBuffer(window, buf);
}
__attribute__ ((visibility ("default")))
GonkDisplay*
GetGonkDisplay()
{
if (!sGonkDisplay)
sGonkDisplay = new GonkDisplayICS();
return sGonkDisplay;
}
} // namespace mozilla

View File

@ -0,0 +1,53 @@
/* Copyright 2013 Mozilla Foundation and Mozilla contributors
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GONKDISPLAYICS_H
#define GONKDISPLAYICS_H
#include <string.h>
#include "GonkDisplay.h"
#include "ui/FramebufferNativeWindow.h"
#include "hardware/hwcomposer.h"
#include "utils/RefBase.h"
namespace mozilla {
class GonkDisplayICS : public GonkDisplay {
public:
GonkDisplayICS();
~GonkDisplayICS();
virtual ANativeWindow* GetNativeWindow();
virtual void SetEnabled(bool enabled);
virtual void* GetHWCDevice();
virtual bool SwapBuffers(EGLDisplay dpy, EGLSurface sur);
virtual ANativeWindowBuffer* DequeueBuffer();
virtual bool QueueBuffer(ANativeWindowBuffer* handle);
private:
hw_module_t const* mModule;
hwc_composer_device_t* mHwc;
android::sp<android::FramebufferNativeWindow> mFBSurface;
};
}
#endif /* GONKDISPLAYICS_H */

View File

@ -0,0 +1,172 @@
/* Copyright 2013 Mozilla Foundation and Mozilla contributors
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "GonkDisplayJB.h"
#include <gui/SurfaceTextureClient.h>
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
#include <suspend/autosuspend.h>
#include "GraphicBufferAlloc.h"
#include "BootAnimation.h"
using namespace android;
namespace mozilla {
static GonkDisplayJB* sGonkDisplay = nullptr;
GonkDisplayJB::GonkDisplayJB()
: mList(nullptr)
, mModule(nullptr)
, mHwc(nullptr)
{
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
if (err)
return;
err = hwc_open_1(mModule, &mHwc);
ALOGE_IF(err, "%s device failed to initialize (%s)",
HWC_HARDWARE_COMPOSER, strerror(-err));
int32_t values[3];
const uint32_t attrs[] = {
HWC_DISPLAY_WIDTH,
HWC_DISPLAY_HEIGHT,
HWC_DISPLAY_DPI_X,
HWC_DISPLAY_NO_ATTRIBUTE
};
mHwc->getDisplayAttributes(mHwc, 0, 0, attrs, values);
mWidth = values[0];
mHeight = values[1];
xdpi = values[2];
surfaceformat = HAL_PIXEL_FORMAT_RGBA_8888;
mAlloc = new GraphicBufferAlloc();
mFBSurface = new FramebufferSurface(0, mWidth, mHeight, surfaceformat, mAlloc);
sp<SurfaceTextureClient> stc = new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >(mFBSurface->getBufferQueue()));
mSTClient = stc;
mList = (hwc_display_contents_1_t *)malloc(sizeof(*mList) + (sizeof(hwc_layer_1_t)*2));
mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, 0);
status_t error;
mBootAnimBuffer = mAlloc->createGraphicBuffer(mWidth, mHeight, surfaceformat, GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER, &error);
StartBootAnimation();
}
GonkDisplayJB::~GonkDisplayJB()
{
if (mHwc)
hwc_close_1(mHwc);
free(mList);
}
ANativeWindow*
GonkDisplayJB::GetNativeWindow()
{
return mSTClient.get();
}
void
GonkDisplayJB::SetEnabled(bool enabled)
{
if (enabled) {
autosuspend_disable();
mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, false);
} else {
mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, true);
autosuspend_enable();
}
}
void*
GonkDisplayJB::GetHWCDevice()
{
return mHwc;
}
bool
GonkDisplayJB::SwapBuffers(EGLDisplay dpy, EGLSurface sur)
{
StopBootAnimation();
mBootAnimBuffer = nullptr;
mList->dpy = dpy;
mList->sur = sur;
eglSwapBuffers(dpy, sur);
return Post(mFBSurface->lastHandle, mFBSurface->lastFenceFD);
}
bool
GonkDisplayJB::Post(buffer_handle_t buf, int fence)
{
hwc_display_contents_1_t *displays[HWC_NUM_DISPLAY_TYPES] = {NULL};
const hwc_rect_t r = { 0, 0, mWidth, mHeight };
displays[HWC_DISPLAY_PRIMARY] = mList;
mList->retireFenceFd = -1;
mList->numHwLayers = 2;
mList->flags = HWC_GEOMETRY_CHANGED;
mList->hwLayers[0].compositionType = HWC_BACKGROUND;
mList->hwLayers[0].hints = 0;
mList->hwLayers[0].flags = 0;
mList->hwLayers[0].backgroundColor = {0};
mList->hwLayers[1].compositionType = HWC_FRAMEBUFFER_TARGET;
mList->hwLayers[1].hints = 0;
mList->hwLayers[1].flags = 0;
mList->hwLayers[1].handle = buf;
mList->hwLayers[1].transform = 0;
mList->hwLayers[1].blending = HWC_BLENDING_PREMULT;
mList->hwLayers[1].sourceCrop = r;
mList->hwLayers[1].displayFrame = r;
mList->hwLayers[1].visibleRegionScreen.numRects = 1;
mList->hwLayers[1].visibleRegionScreen.rects = &mList->hwLayers[0].sourceCrop;
mList->hwLayers[1].acquireFenceFd = fence;
mList->hwLayers[1].releaseFenceFd = -1;
mHwc->prepare(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
int err = mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
mFBSurface->setReleaseFenceFd(mList->hwLayers[1].releaseFenceFd);
if (mList->retireFenceFd >= 0)
close(mList->retireFenceFd);
return !err;
}
ANativeWindowBuffer*
GonkDisplayJB::DequeueBuffer()
{
return static_cast<ANativeWindowBuffer*>(mBootAnimBuffer.get());
}
bool
GonkDisplayJB::QueueBuffer(ANativeWindowBuffer* buf)
{
bool success = Post(buf->handle, -1);
return success;
}
__attribute__ ((visibility ("default")))
GonkDisplay*
GetGonkDisplay()
{
if (!sGonkDisplay)
sGonkDisplay = new GonkDisplayJB();
return sGonkDisplay;
}
} // namespace mozilla

View File

@ -0,0 +1,59 @@
/* Copyright 2013 Mozilla Foundation and Mozilla contributors
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GONKDISPLAYJB_H
#define GONKDISPLAYJB_H
#include "GonkDisplay.h"
#include "FramebufferSurface.h"
#include "hardware/hwcomposer.h"
#include "utils/RefBase.h"
namespace mozilla {
class GonkDisplayJB : public GonkDisplay {
public:
GonkDisplayJB();
~GonkDisplayJB();
virtual ANativeWindow* GetNativeWindow();
virtual void SetEnabled(bool enabled);
virtual void* GetHWCDevice();
virtual bool SwapBuffers(EGLDisplay dpy, EGLSurface sur);
virtual ANativeWindowBuffer* DequeueBuffer();
virtual bool QueueBuffer(ANativeWindowBuffer* buf);
bool Post(buffer_handle_t buf, int fence);
private:
hw_module_t const* mModule;
hwc_composer_device_1_t* mHwc;
android::sp<android::FramebufferSurface> mFBSurface;
android::sp<ANativeWindow> mSTClient;
android::sp<android::IGraphicBufferAlloc> mAlloc;
android::sp<android::GraphicBuffer> mBootAnimBuffer;
hwc_display_contents_1_t* mList;
uint32_t mWidth;
uint32_t mHeight;
};
}
#endif /* GONKDISPLAYJB_H */

View File

@ -0,0 +1,53 @@
/*
**
** Copyright 2012 The Android Open Source Project
**
** Licensed under the Apache License Version 2.0(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.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing software
** distributed under the License is distributed on an "AS IS" BASIS
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#include <cutils/log.h>
#include <ui/GraphicBuffer.h>
#include "GraphicBufferAlloc.h"
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
GraphicBufferAlloc::GraphicBufferAlloc() {
}
GraphicBufferAlloc::~GraphicBufferAlloc() {
}
sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
PixelFormat format, uint32_t usage, status_t* error) {
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
status_t err = graphicBuffer->initCheck();
*error = err;
if (err != 0 || graphicBuffer->handle == 0) {
if (err == NO_MEMORY) {
GraphicBuffer::dumpAllocationsToSystemLog();
}
ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
"failed (%s), handle=%p",
w, h, strerror(-err), graphicBuffer->handle);
return 0;
}
return graphicBuffer;
}
// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,46 +14,31 @@
* limitations under the License.
*/
#ifndef ANDROID_SF_HWCOMPOSER_H
#define ANDROID_SF_HWCOMPOSER_H
#ifndef ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
#define ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
#include <utils/Vector.h>
#include <stdint.h>
#include <sys/types.h>
#include "hardware/hwcomposer.h"
#include <gui/IGraphicBufferAlloc.h>
#include <ui/PixelFormat.h>
#include <utils/Errors.h>
namespace android {
// ---------------------------------------------------------------------------
class String8;
class GraphicBuffer;
class HWComposer
{
class GraphicBufferAlloc : public BnGraphicBufferAlloc {
public:
HWComposer();
~HWComposer();
int init();
// swap buffers using vendor specific implementation
status_t swapBuffers(hwc_display_t dpy, hwc_surface_t surf) const;
protected:
struct cb_context {
hwc_procs_t procs;
HWComposer* hwc;
};
void invalidate();
hw_module_t const* mModule;
hwc_composer_device_t* mHwc;
hwc_display_t mDpy;
hwc_surface_t mSur;
cb_context mCBContext;
GraphicBufferAlloc();
virtual ~GraphicBufferAlloc();
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
PixelFormat format, uint32_t usage, status_t* error);
};
// ---------------------------------------------------------------------------
}; // namespace android
#endif // ANDROID_SF_HWCOMPOSER_H
#endif // ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H

View File

@ -0,0 +1,54 @@
# Copyright 2013 Mozilla Foundation and Mozilla contributors
#
# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = \
$(srcdir) \
$(NULL)
include $(DEPTH)/config/autoconf.mk
LIBRARY_NAME = display
FORCE_STATIC_LIB= 1
STL_FLAGS=
CPPSRCS = BootAnimation.cpp
ifeq (17,$(ANDROID_VERSION))
CPPSRCS += \
FramebufferSurface.cpp \
GraphicBufferAlloc.cpp \
GonkDisplayJB.cpp \
$(NULL)
else ifeq (15,$(ANDROID_VERSION))
CPPSRCS += GonkDisplayICS.cpp
else
$(error Unsupported platform version: $(ANDROID_VERSION))
endif
include $(topsrcdir)/config/rules.mk
DEFINES += -DXPCOM_GLUE
LOCAL_INCLUDES += \
-I$(ANDROID_SOURCE)/hardware/libhardware/include \
-I$(ANDROID_SOURCE)/hardware/libhardware_legacy/include \
-I$(ANDROID_SOURCE)/frameworks/native/opengl/include \
-I$(ANDROID_SOURCE)/system/core/libsuspend/include \
-I$(srcdir) \
$(NULL)
include $(topsrcdir)/ipc/chromium/chromium-config.mk

View File

@ -0,0 +1,17 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# Copyright 2013 Mozilla Foundation and Mozilla contributors
#
# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
MODULE = 'display'

View File

@ -20,3 +20,4 @@ EXPORTS += [
'OrientationObserver.h',
]
DIRS += ['libdisplay']

View File

@ -15,25 +15,19 @@
#include "mozilla/DebugOnly.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <fcntl.h>
#include "android/log.h"
#include "ui/FramebufferNativeWindow.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/Hal.h"
#include "mozilla/Preferences.h"
#include "mozilla/FileUtils.h"
#include "BootAnimation.h"
#include "Framebuffer.h"
#include "gfxContext.h"
#include "gfxPlatform.h"
#include "gfxUtils.h"
#include "GLContextProvider.h"
#include "HwcComposer2D.h"
#include "LayerManagerOGL.h"
#include "nsAutoPtr.h"
#include "nsAppShell.h"
@ -45,6 +39,12 @@
#include "cutils/properties.h"
#include "ClientLayerManager.h"
#include "BasicLayers.h"
#include "libdisplay/GonkDisplay.h"
#include "pixelflinger/format.h"
#if ANDROID_VERSION == 15
#include "HwcComposer2D.h"
#endif
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
#define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "Gonk", ## args)
@ -480,7 +480,7 @@ nsWindow::GetNativeData(uint32_t aDataType)
{
switch (aDataType) {
case NS_NATIVE_WINDOW:
return NativeWindow();
return GetGonkDisplay()->GetNativeWindow();
case NS_NATIVE_WIDGET:
return this;
}
@ -541,7 +541,7 @@ nsWindow::MakeFullScreen(bool aFullScreen)
float
nsWindow::GetDPI()
{
return NativeWindow()->xdpi;
return GetGonkDisplay()->xdpi;
}
double
@ -580,8 +580,6 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
return mLayerManager;
}
StopBootAnimation();
// Set mUseLayersAcceleration here to make it consistent with
// nsBaseWidget::GetLayerManager
mUseLayersAcceleration = ComputeShouldAccelerate(mUseLayersAcceleration);
@ -707,9 +705,13 @@ nsWindow::GetComposer2D()
if (!sUsingHwc) {
return nullptr;
}
#if ANDROID_VERSION == 15
if (HwcComposer2D* hwc = HwcComposer2D::GetInstance()) {
return hwc->Initialized() ? hwc : nullptr;
}
#endif
return nullptr;
}
@ -746,7 +748,7 @@ nsScreenGonk::GetAvailRect(int32_t *outLeft, int32_t *outTop,
static uint32_t
ColorDepth()
{
switch (NativeWindow()->getDevice()->format) {
switch (GetGonkDisplay()->surfaceformat) {
case GGL_PIXEL_FORMAT_RGB_565:
return 16;
case GGL_PIXEL_FORMAT_RGBA_8888: