mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to inbound.
This commit is contained in:
commit
4d351a9351
@ -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 */
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
30
python/mach/bash-completion.sh
Normal file
30
python/mach/bash-completion.sh
Normal 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
|
@ -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
|
||||
|
@ -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':
|
||||
|
@ -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.
|
||||
|
@ -18,11 +18,11 @@ ifdef MOZ_UPDATER
|
||||
|
||||
EXTRA_PP_COMPONENTS += \
|
||||
nsUpdateService.js \
|
||||
nsUpdateServiceStub.js \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_COMPONENTS += \
|
||||
nsUpdateService.manifest \
|
||||
nsUpdateServiceStub.js \
|
||||
$(NULL)
|
||||
|
||||
endif
|
||||
|
@ -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.
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
@ -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]
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -954,6 +954,28 @@ GetRegWindowsAppDataFolder(bool aLocal, nsAString& _retval)
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetCachedHash(HKEY rootKey, const nsAString ®Path, 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);
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 \
|
||||
|
@ -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()
|
||||
{
|
24
widget/gonk/libdisplay/BootAnimation.h
Normal file
24
widget/gonk/libdisplay/BootAnimation.h
Normal 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 */
|
160
widget/gonk/libdisplay/FramebufferSurface.cpp
Normal file
160
widget/gonk/libdisplay/FramebufferSurface.cpp
Normal 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
|
||||
// ----------------------------------------------------------------------------
|
84
widget/gonk/libdisplay/FramebufferSurface.h
Normal file
84
widget/gonk/libdisplay/FramebufferSurface.h
Normal 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
|
||||
|
48
widget/gonk/libdisplay/GonkDisplay.h
Normal file
48
widget/gonk/libdisplay/GonkDisplay.h
Normal 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 */
|
141
widget/gonk/libdisplay/GonkDisplayICS.cpp
Normal file
141
widget/gonk/libdisplay/GonkDisplayICS.cpp
Normal 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
|
53
widget/gonk/libdisplay/GonkDisplayICS.h
Normal file
53
widget/gonk/libdisplay/GonkDisplayICS.h
Normal 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 */
|
172
widget/gonk/libdisplay/GonkDisplayJB.cpp
Normal file
172
widget/gonk/libdisplay/GonkDisplayJB.cpp
Normal 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
|
59
widget/gonk/libdisplay/GonkDisplayJB.h
Normal file
59
widget/gonk/libdisplay/GonkDisplayJB.h
Normal 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 */
|
53
widget/gonk/libdisplay/GraphicBufferAlloc.cpp
Normal file
53
widget/gonk/libdisplay/GraphicBufferAlloc.cpp
Normal 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
|
||||
// ----------------------------------------------------------------------------
|
@ -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
|
54
widget/gonk/libdisplay/Makefile.in
Normal file
54
widget/gonk/libdisplay/Makefile.in
Normal 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
|
17
widget/gonk/libdisplay/moz.build
Normal file
17
widget/gonk/libdisplay/moz.build
Normal 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'
|
@ -20,3 +20,4 @@ EXPORTS += [
|
||||
'OrientationObserver.h',
|
||||
]
|
||||
|
||||
DIRS += ['libdisplay']
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user