Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Bug 1107714 - [Gallery] When setting a wallpaper in landscape, the wa…
Browse files Browse the repository at this point in the history
…llpaper will expand from its normal size r=djf
  • Loading branch information
David Flanagan authored and rvandermeulen committed Jan 23, 2015
1 parent 91495dc commit dda723b
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 17 deletions.
23 changes: 19 additions & 4 deletions apps/system/js/wallpaper_manager.js
@@ -1,7 +1,7 @@
/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

/* global ImageUtils, LazyLoader */
/* global ImageUtils, LazyLoader, OrientationManager */

'use strict';

Expand Down Expand Up @@ -226,9 +226,24 @@
if (!this._started) { return; }
debug('resizing wallpaper if needed');

// How big (in device pixels) is the screen?
var screenWidth = Math.ceil(screen.width * window.devicePixelRatio);
var screenHeight = Math.ceil(screen.height * window.devicePixelRatio);
// How big (in device pixels) is the screen in its default orientation?
var screenWidth, screenHeight;
if (OrientationManager && !OrientationManager.isDefaultPortrait()) {
// The screen.width and screen.height values depend on how the
// user is holding the device. If this is a tablet or other
// device with a screen that defaults to landscape mode, then
// with width is the bigger dimension
screenWidth = Math.max(screen.width, screen.height);
screenHeight = Math.min(screen.width, screen.height);
} else {
// Otherwise, the width is the smaller dimension
screenWidth = Math.min(screen.width, screen.height);
screenHeight = Math.max(screen.width, screen.height);
}

// Use device pixels, not CSS pixels
screenWidth = Math.ceil(screenWidth * window.devicePixelRatio);
screenHeight = Math.ceil(screenHeight * window.devicePixelRatio);

// For performance we need to guarantee that the size of the wallpaper
// is exactly the same as the size of the screen. LazyLoad the
Expand Down
81 changes: 77 additions & 4 deletions apps/system/test/unit/wallpaper_manager_test.js
@@ -1,7 +1,9 @@
'use strict';

/* global WallpaperManager, LazyLoader, ImageUtils, MockNavigatorSettings */
/* global WallpaperManager, LazyLoader, ImageUtils,
MockNavigatorSettings, MockOrientationManager */

requireApp('system/test/unit/mock_orientation_manager.js');
require('/shared/test/unit/mocks/mock_navigator_moz_settings.js');
require('/shared/js/image_utils.js');
require('/apps/system/js/wallpaper_manager.js');
Expand All @@ -16,6 +18,7 @@ suite('WallpaperManager', function() {

suiteSetup(function(done) {
var self = this;
var sw, sh;

// Don't display debug output
WallpaperManager.DEBUG = false;
Expand All @@ -42,10 +45,20 @@ suite('WallpaperManager', function() {
});
};

// Create some image blobs
this.screenWidth = screen.width * window.devicePixelRatio;
this.screenHeight = screen.height * window.devicePixelRatio;
// How big (in device pixels) is the screen in its default orientation?
if (MockOrientationManager && !MockOrientationManager.isDefaultPortrait()) {
sw = Math.max(screen.width, screen.height);
sh = Math.min(screen.width, screen.height);
} else {
// Otherwise, the width is the smaller dimension
sw = Math.min(screen.width, screen.height);
sh = Math.max(screen.width, screen.height);
}

this.screenWidth = sw * window.devicePixelRatio;
this.screenHeight = sh * window.devicePixelRatio;

// Create some image blobs
var canvas = document.createElement('canvas');
canvas.width = this.screenWidth;
canvas.height = this.screenHeight;
Expand Down Expand Up @@ -84,6 +97,9 @@ suite('WallpaperManager', function() {
this.realMozSettings = navigator.mozSettings;
navigator.mozSettings = MockNavigatorSettings;

this.realOrientationManager = window.OrientationManager;
window.OrientationManager = MockOrientationManager;

mockPublish = function(e) {
if (self.onWallpaperChange) {
setTimeout(function() {
Expand Down Expand Up @@ -126,6 +142,9 @@ suite('WallpaperManager', function() {
navigator.mozSettings = this.realMozSettings;
MockNavigatorSettings.mTeardown();

window.OrientationManager = this.realOrientationManager;
MockOrientationManager.defaultOrientation = 'portrait-primary';

this.onWallpaperChange = null;
});

Expand Down Expand Up @@ -343,6 +362,60 @@ suite('WallpaperManager', function() {
subject.start();
});

//
// Test changed wallpaper in landscape orientation. Verify that
// the wallpaper is resized and that the resulting wallpaper has
// the expected size.
//
test('start and change wallpaper in landscape mode', function(done) {
var self = this;
MockOrientationManager.defaultOrientation = 'landscape-primary';
// Start with a validated blob in the settings db
MockNavigatorSettings.mSettings['wallpaper.image'] = wallpaperBlob;
MockNavigatorSettings.mSettings['wallpaper.image.valid'] = true;

// Wait 'till the initial wallpaper is published
this.onWallpaperChange = function(type, data) {
// Test assertions when we get the changed wallpaper
self.onWallpaperChange = function(type, data) {
// Check event type
assert.equal(type, 'wallpaperchange');
// Check that we get a blob url
assert.equal(data.url.substring(0, 5), 'blob:');
// Check that the methods were called the expected number of times

// 3 times: initial, changed, and saved wallpapers
assert.equal(self.setWallpaperSpy.callCount, 3);
assert.ok(self.toBlobSpy.notCalled, '_toBlob not called');
assert.ok(LazyLoader.load.calledOnce);
assert.ok(self.checkSizeSpy.calledOnce, 'checkSize called');
assert.ok(self.saveSpy.calledOnce, 'save called');
assert.ok(self.validateSpy.notCalled,
'validate not called');
assert.equal(self.publishSpy.callCount, 2, 'publish called');
assert.notEqual(MockNavigatorSettings.mSettings['wallpaper.image'],
wallpaperBlob);
assert.equal(MockNavigatorSettings.mSettings['wallpaper.image.valid'],
true);

var blob = MockNavigatorSettings.mSettings['wallpaper.image'];
ImageUtils.getSizeAndType(blob).then(function resolve(data) {
// Check the resized wallpaper in landscape orientation to have
// width as bigger dimension that equals screenHeight.
assert.equal(data.width, self.screenHeight);
assert.equal(data.height, self.screenWidth);
done();
});
};

navigator.mozSettings.createLock().set({
'wallpaper.image': wallpaperBlob
});
};

subject.start();
});

//
// The tests that follow call this utility function and test what happens
// when we use URLs and invalid values as the wallpaper value.
Expand Down
53 changes: 44 additions & 9 deletions apps/wallpaper/js/share.js
Expand Up @@ -26,9 +26,38 @@ window.onload = function() {
var scale;
var previewImage = document.getElementById('previewImage');

// How big (in device pixels) is the screen?
var screenWidth = Math.ceil(screen.width * window.devicePixelRatio);
var screenHeight = Math.ceil(screen.height * window.devicePixelRatio);
// For the computations below, we need to know the full size of the screen
// in device pixels and the size of the window in CSS pixels. (The window
// and screen sizes can be different if there is a software home button.)
// We also need to ensure that the dimensions match the default orientation
// of the screen, even if the user is holding the device in a different
// orientation, and we want this to work for both phones (portrait) and
// tablets (landscape). This app is supposed to be locked to the default
// device orientation, but when it is launched as an activity from a
// different orientation sometimes it starts up in the wrong screen and
// window size. So we need to be careful to work around that window
// management bug, too.
var screenWidth, screenHeight;
var windowWidth, windowHeight;
if (screen.mozOrientation && screen.mozOrientation.startsWith('landscape')) {
// Since our manifest locks us to default orientation, mozOrientation
// should return that default orientation. If landscape then width is
// the larger dimension
screenWidth = Math.max(screen.width, screen.height);
windowWidth = Math.max(window.innerWidth, window.innerHeight);
screenHeight = Math.min(screen.width, screen.height);
windowHeight = Math.min(window.innerWidth, window.innerHeight);
} else {
// Otherwise, portrait is the default and width is the smaller dimension
screenWidth = Math.min(screen.width, screen.height);
windowWidth = Math.min(window.innerWidth, window.innerHeight);
screenHeight = Math.max(screen.width, screen.height);
windowHeight = Math.max(window.innerWidth, window.innerHeight);
}

// For the screen size we care about device pixels, not CSS pixels
screenWidth = Math.ceil(screenWidth * window.devicePixelRatio);
screenHeight = Math.ceil(screenHeight * window.devicePixelRatio);

function startShare(request) {
cancelButton.addEventListener('click', cancelShare);
Expand Down Expand Up @@ -70,8 +99,8 @@ window.onload = function() {

// Compute a scale that will make the image at least as big as
// the screen in both dimensions.
var scalex = window.innerWidth / previewImage.width;
var scaley = window.innerHeight / previewImage.height;
var scalex = windowWidth / previewImage.width;
var scaley = windowHeight / previewImage.height;
scale = Math.max(scalex, scaley);

// Apply that scale to the image. Note that scaling width will
Expand All @@ -82,8 +111,8 @@ window.onload = function() {
// out how to center the image on the screen and compute how much
// the user will be able to pan the image left and right or up
// and down.
limitX = window.innerWidth - previewImage.width;
limitY = window.innerHeight - previewImage.height;
limitX = windowWidth - previewImage.width;
limitY = windowHeight - previewImage.height;

posX = Math.round(limitX / 2);
posY = Math.round(limitY / 2);
Expand Down Expand Up @@ -117,15 +146,21 @@ window.onload = function() {
}

function scaleImage() {
// Disable set wallpaper button to prevent hammering
// and causing multiple calls to scaleImage.
setButton.disabled = true;

// Create a canvas to have an image that is exactly
// the size of the screen in device pixels.
var canvas = document.createElement('canvas');
// To have an image which matches the device pixel, we need to multiply
// window.devicePixelRatio.
canvas.width = screenWidth;
canvas.height = screenHeight;
var ctx = canvas.getContext('2d');

var w = Math.round(window.innerWidth / scale);
var h = Math.round(window.innerHeight / scale);
var w = Math.round(windowWidth / scale);
var h = Math.round(windowHeight / scale);
var x = Math.round(-1 * posX / scale);
var y = Math.round(-1 * posY / scale);

Expand Down

0 comments on commit dda723b

Please sign in to comment.