| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "extensions/browser/app_window/app_window.h" | 5 #include "extensions/browser/app_window/app_window.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 #include "extensions/browser/extension_web_contents_observer.h" | 42 #include "extensions/browser/extension_web_contents_observer.h" |
| 43 #include "extensions/browser/extensions_browser_client.h" | 43 #include "extensions/browser/extensions_browser_client.h" |
| 44 #include "extensions/browser/notification_types.h" | 44 #include "extensions/browser/notification_types.h" |
| 45 #include "extensions/browser/process_manager.h" | 45 #include "extensions/browser/process_manager.h" |
| 46 #include "extensions/browser/suggest_permission_util.h" | 46 #include "extensions/browser/suggest_permission_util.h" |
| 47 #include "extensions/browser/view_type_utils.h" | 47 #include "extensions/browser/view_type_utils.h" |
| 48 #include "extensions/common/draggable_region.h" | 48 #include "extensions/common/draggable_region.h" |
| 49 #include "extensions/common/extension.h" | 49 #include "extensions/common/extension.h" |
| 50 #include "extensions/common/manifest_handlers/icons_handler.h" | 50 #include "extensions/common/manifest_handlers/icons_handler.h" |
| 51 #include "extensions/common/permissions/permissions_data.h" | 51 #include "extensions/common/permissions/permissions_data.h" |
| 52 #include "extensions/grit/extensions_browser_resources.h" | 52 #include "third_party/skia/include/core/SkBitmap.h" |
| 53 #include "third_party/skia/include/core/SkRegion.h" | 53 #include "third_party/skia/include/core/SkRegion.h" |
| 54 #include "ui/base/resource/resource_bundle.h" | |
| 55 #include "ui/display/display.h" | 54 #include "ui/display/display.h" |
| 56 #include "ui/display/screen.h" | 55 #include "ui/display/screen.h" |
| 57 #include "ui/events/keycodes/keyboard_codes.h" | 56 #include "ui/events/keycodes/keyboard_codes.h" |
| 58 #include "ui/gfx/image/image_skia_operations.h" | |
| 59 | 57 |
| 60 #if !defined(OS_MACOSX) | 58 #if !defined(OS_MACOSX) |
| 61 #include "components/prefs/pref_service.h" | 59 #include "components/prefs/pref_service.h" |
| 62 #include "extensions/browser/pref_names.h" | 60 #include "extensions/browser/pref_names.h" |
| 63 #endif | 61 #endif |
| 64 | 62 |
| 65 using content::BrowserContext; | 63 using content::BrowserContext; |
| 66 using content::ConsoleMessageLevel; | 64 using content::ConsoleMessageLevel; |
| 67 using content::WebContents; | 65 using content::WebContents; |
| 68 using web_modal::WebContentsModalDialogHost; | 66 using web_modal::WebContentsModalDialogHost; |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 window_key_ = new_params.window_key; | 284 window_key_ = new_params.window_key; |
| 287 | 285 |
| 288 // Windows cannot be always-on-top in fullscreen mode for security reasons. | 286 // Windows cannot be always-on-top in fullscreen mode for security reasons. |
| 289 cached_always_on_top_ = new_params.always_on_top; | 287 cached_always_on_top_ = new_params.always_on_top; |
| 290 if (new_params.state == ui::SHOW_STATE_FULLSCREEN) | 288 if (new_params.state == ui::SHOW_STATE_FULLSCREEN) |
| 291 new_params.always_on_top = false; | 289 new_params.always_on_top = false; |
| 292 | 290 |
| 293 requested_alpha_enabled_ = new_params.alpha_enabled; | 291 requested_alpha_enabled_ = new_params.alpha_enabled; |
| 294 is_ime_window_ = params.is_ime_window; | 292 is_ime_window_ = params.is_ime_window; |
| 295 show_in_shelf_ = params.show_in_shelf; | 293 show_in_shelf_ = params.show_in_shelf; |
| 296 window_icon_url_ = params.window_icon_url; | |
| 297 | 294 |
| 298 AppWindowClient* app_window_client = AppWindowClient::Get(); | 295 AppWindowClient* app_window_client = AppWindowClient::Get(); |
| 299 native_app_window_.reset( | 296 native_app_window_.reset( |
| 300 app_window_client->CreateNativeAppWindow(this, &new_params)); | 297 app_window_client->CreateNativeAppWindow(this, &new_params)); |
| 301 | 298 |
| 302 helper_.reset(new AppWebContentsHelper( | 299 helper_.reset(new AppWebContentsHelper( |
| 303 browser_context_, extension_id_, web_contents(), app_delegate_.get())); | 300 browser_context_, extension_id_, web_contents(), app_delegate_.get())); |
| 304 | 301 |
| 305 UpdateExtensionAppIcon(); | 302 native_app_window_->UpdateWindowIcon(); |
| 306 // Download showInShelf=true window icon. | 303 |
| 307 if (window_icon_url_.is_valid()) | 304 if (params.window_icon_url.is_valid()) |
| 308 SetAppIconUrl(window_icon_url_); | 305 SetAppIconUrl(params.window_icon_url); |
| 309 | 306 |
| 310 AppWindowRegistry::Get(browser_context_)->AddAppWindow(this); | 307 AppWindowRegistry::Get(browser_context_)->AddAppWindow(this); |
| 311 | 308 |
| 312 if (new_params.hidden) { | 309 if (new_params.hidden) { |
| 313 // Although the window starts hidden by default, calling Hide() here | 310 // Although the window starts hidden by default, calling Hide() here |
| 314 // notifies observers of the window being hidden. | 311 // notifies observers of the window being hidden. |
| 315 Hide(); | 312 Hide(); |
| 316 } else { | 313 } else { |
| 317 // Panels are not activated by default. | 314 // Panels are not activated by default. |
| 318 Show(window_type_is_panel() || !new_params.focused ? SHOW_INACTIVE | 315 Show(window_type_is_panel() || !new_params.focused ? SHOW_INACTIVE |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 web_contents()->GetController().GetLastCommittedEntry() : nullptr; | 551 web_contents()->GetController().GetLastCommittedEntry() : nullptr; |
| 555 if (!entry || entry->GetTitle().empty()) { | 552 if (!entry || entry->GetTitle().empty()) { |
| 556 title = base::UTF8ToUTF16(extension->name()); | 553 title = base::UTF8ToUTF16(extension->name()); |
| 557 } else { | 554 } else { |
| 558 title = web_contents()->GetTitle(); | 555 title = web_contents()->GetTitle(); |
| 559 } | 556 } |
| 560 base::RemoveChars(title, base::ASCIIToUTF16("\n"), &title); | 557 base::RemoveChars(title, base::ASCIIToUTF16("\n"), &title); |
| 561 return title; | 558 return title; |
| 562 } | 559 } |
| 563 | 560 |
| 564 bool AppWindow::HasCustomIcon() const { | |
| 565 return window_icon_url_.is_valid() || app_icon_url_.is_valid(); | |
| 566 } | |
| 567 | |
| 568 void AppWindow::SetAppIconUrl(const GURL& url) { | 561 void AppWindow::SetAppIconUrl(const GURL& url) { |
| 569 // Avoid using any previous icons that were being downloaded. | 562 // Avoid using any previous icons that were being downloaded. |
| 570 image_loader_ptr_factory_.InvalidateWeakPtrs(); | 563 image_loader_ptr_factory_.InvalidateWeakPtrs(); |
| 571 | 564 app_icon_url_ = url; |
| 572 // Reset |app_icon_image_| to abort pending image load (if any). | |
| 573 if (!show_in_shelf_) { | |
| 574 app_icon_image_.reset(); | |
| 575 app_icon_url_ = url; | |
| 576 } else { | |
| 577 window_icon_url_ = url; | |
| 578 } | |
| 579 | |
| 580 web_contents()->DownloadImage( | 565 web_contents()->DownloadImage( |
| 581 url, | 566 url, |
| 582 true, // is a favicon | 567 true, // is a favicon |
| 583 0, // no maximum size | 568 0, // no maximum size |
| 584 false, // normal cache policy | 569 false, // normal cache policy |
| 585 base::Bind(&AppWindow::DidDownloadFavicon, | 570 base::Bind(&AppWindow::DidDownloadFavicon, |
| 586 image_loader_ptr_factory_.GetWeakPtr())); | 571 image_loader_ptr_factory_.GetWeakPtr())); |
| 587 } | 572 } |
| 588 | 573 |
| 589 void AppWindow::UpdateShape(std::unique_ptr<SkRegion> region) { | 574 void AppWindow::UpdateShape(std::unique_ptr<SkRegion> region) { |
| 590 native_app_window_->UpdateShape(std::move(region)); | 575 native_app_window_->UpdateShape(std::move(region)); |
| 591 } | 576 } |
| 592 | 577 |
| 593 void AppWindow::UpdateDraggableRegions( | 578 void AppWindow::UpdateDraggableRegions( |
| 594 const std::vector<DraggableRegion>& regions) { | 579 const std::vector<DraggableRegion>& regions) { |
| 595 native_app_window_->UpdateDraggableRegions(regions); | 580 native_app_window_->UpdateDraggableRegions(regions); |
| 596 } | 581 } |
| 597 | 582 |
| 598 void AppWindow::UpdateAppIcon(const gfx::Image& image) { | 583 void AppWindow::UpdateAppIcon(const gfx::Image& image) { |
| 599 // Set the showInShelf=true window icon and add the app_icon_image_ | 584 if (image.IsEmpty()) |
| 600 // as a badge. If the image is empty, set the default app icon placeholder | 585 return; |
| 601 // as the base image. | 586 custom_app_icon_ = image; |
| 602 if (window_icon_url_.is_valid() && app_icon_image_ && | |
| 603 !app_icon_image_->image().IsEmpty()) { | |
| 604 gfx::Image base_image = | |
| 605 !image.IsEmpty() | |
| 606 ? image | |
| 607 : gfx::Image(*ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
| 608 IDR_APP_DEFAULT_ICON)); | |
| 609 // Scale the icon to EXTENSION_ICON_LARGE. | |
| 610 const int large_icon_size = extension_misc::EXTENSION_ICON_LARGE; | |
| 611 if (base_image.Width() != large_icon_size || | |
| 612 base_image.Height() != large_icon_size) { | |
| 613 gfx::ImageSkia resized_image = | |
| 614 gfx::ImageSkiaOperations::CreateResizedImage( | |
| 615 base_image.AsImageSkia(), skia::ImageOperations::RESIZE_BEST, | |
| 616 gfx::Size(large_icon_size, large_icon_size)); | |
| 617 app_icon_ = gfx::Image(gfx::ImageSkiaOperations::CreateIconWithBadge( | |
| 618 resized_image, app_icon_image_->image_skia())); | |
| 619 } else { | |
| 620 app_icon_ = gfx::Image(gfx::ImageSkiaOperations::CreateIconWithBadge( | |
| 621 base_image.AsImageSkia(), app_icon_image_->image_skia())); | |
| 622 } | |
| 623 } else { | |
| 624 if (image.IsEmpty()) | |
| 625 return; | |
| 626 | |
| 627 app_icon_ = image; | |
| 628 } | |
| 629 native_app_window_->UpdateWindowIcon(); | 587 native_app_window_->UpdateWindowIcon(); |
| 630 AppWindowRegistry::Get(browser_context_)->AppWindowIconChanged(this); | |
| 631 } | 588 } |
| 632 | 589 |
| 633 void AppWindow::SetFullscreen(FullscreenType type, bool enable) { | 590 void AppWindow::SetFullscreen(FullscreenType type, bool enable) { |
| 634 DCHECK_NE(FULLSCREEN_TYPE_NONE, type); | 591 DCHECK_NE(FULLSCREEN_TYPE_NONE, type); |
| 635 | 592 |
| 636 if (enable) { | 593 if (enable) { |
| 637 #if !defined(OS_MACOSX) | 594 #if !defined(OS_MACOSX) |
| 638 // Do not enter fullscreen mode if disallowed by pref. | 595 // Do not enter fullscreen mode if disallowed by pref. |
| 639 // TODO(bartfab): Add a test once it becomes possible to simulate a user | 596 // TODO(bartfab): Add a test once it becomes possible to simulate a user |
| 640 // gesture. http://crbug.com/174178 | 597 // gesture. http://crbug.com/174178 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 | 762 |
| 806 //------------------------------------------------------------------------------ | 763 //------------------------------------------------------------------------------ |
| 807 // Private methods | 764 // Private methods |
| 808 | 765 |
| 809 void AppWindow::DidDownloadFavicon( | 766 void AppWindow::DidDownloadFavicon( |
| 810 int id, | 767 int id, |
| 811 int http_status_code, | 768 int http_status_code, |
| 812 const GURL& image_url, | 769 const GURL& image_url, |
| 813 const std::vector<SkBitmap>& bitmaps, | 770 const std::vector<SkBitmap>& bitmaps, |
| 814 const std::vector<gfx::Size>& original_bitmap_sizes) { | 771 const std::vector<gfx::Size>& original_bitmap_sizes) { |
| 815 if (((image_url != app_icon_url_) && (image_url != window_icon_url_)) || | 772 if (image_url != app_icon_url_ || bitmaps.empty()) |
| 816 bitmaps.empty()) { | |
| 817 return; | 773 return; |
| 818 } | |
| 819 | 774 |
| 820 // Bitmaps are ordered largest to smallest. Choose the smallest bitmap | 775 // Bitmaps are ordered largest to smallest. Choose the smallest bitmap |
| 821 // whose height >= the preferred size. | 776 // whose height >= the preferred size. |
| 822 int largest_index = 0; | 777 int largest_index = 0; |
| 823 for (size_t i = 1; i < bitmaps.size(); ++i) { | 778 for (size_t i = 1; i < bitmaps.size(); ++i) { |
| 824 if (bitmaps[i].height() < app_delegate_->PreferredIconSize()) | 779 if (bitmaps[i].height() < app_delegate_->PreferredIconSize()) |
| 825 break; | 780 break; |
| 826 largest_index = i; | 781 largest_index = i; |
| 827 } | 782 } |
| 828 const SkBitmap& largest = bitmaps[largest_index]; | 783 const SkBitmap& largest = bitmaps[largest_index]; |
| 829 UpdateAppIcon(gfx::Image::CreateFrom1xBitmap(largest)); | 784 UpdateAppIcon(gfx::Image::CreateFrom1xBitmap(largest)); |
| 830 } | 785 } |
| 831 | 786 |
| 832 void AppWindow::OnExtensionIconImageChanged(IconImage* image) { | |
| 833 DCHECK_EQ(app_icon_image_.get(), image); | |
| 834 | |
| 835 // Update app_icon if no valid window icon url is set. | |
| 836 if (!window_icon_url_.is_valid()) | |
| 837 UpdateAppIcon(gfx::Image(app_icon_image_->image_skia())); | |
| 838 } | |
| 839 | |
| 840 void AppWindow::UpdateExtensionAppIcon() { | |
| 841 // Avoid using any previous app icons were being downloaded. | |
| 842 image_loader_ptr_factory_.InvalidateWeakPtrs(); | |
| 843 | |
| 844 const Extension* extension = GetExtension(); | |
| 845 if (!extension) | |
| 846 return; | |
| 847 | |
| 848 gfx::ImageSkia app_default_icon = | |
| 849 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
| 850 IDR_APP_DEFAULT_ICON); | |
| 851 | |
| 852 app_icon_image_.reset(new IconImage(browser_context(), | |
| 853 extension, | |
| 854 IconsInfo::GetIcons(extension), | |
| 855 app_delegate_->PreferredIconSize(), | |
| 856 app_default_icon, | |
| 857 this)); | |
| 858 | |
| 859 // Triggers actual image loading with 1x resources. The 2x resource will | |
| 860 // be handled by IconImage class when requested. | |
| 861 app_icon_image_->image_skia().GetRepresentation(1.0f); | |
| 862 } | |
| 863 | |
| 864 void AppWindow::SetNativeWindowFullscreen() { | 787 void AppWindow::SetNativeWindowFullscreen() { |
| 865 native_app_window_->SetFullscreen(fullscreen_types_); | 788 native_app_window_->SetFullscreen(fullscreen_types_); |
| 866 | 789 |
| 867 RestoreAlwaysOnTop(); | 790 RestoreAlwaysOnTop(); |
| 868 } | 791 } |
| 869 | 792 |
| 870 bool AppWindow::IntersectsWithTaskbar() const { | 793 bool AppWindow::IntersectsWithTaskbar() const { |
| 871 #if defined(OS_WIN) | 794 #if defined(OS_WIN) |
| 872 display::Screen* screen = display::Screen::GetScreen(); | 795 display::Screen* screen = display::Screen::GetScreen(); |
| 873 gfx::Rect window_bounds = native_app_window_->GetRestoredBounds(); | 796 gfx::Rect window_bounds = native_app_window_->GetRestoredBounds(); |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1118 region.bounds.x(), | 1041 region.bounds.x(), |
| 1119 region.bounds.y(), | 1042 region.bounds.y(), |
| 1120 region.bounds.right(), | 1043 region.bounds.right(), |
| 1121 region.bounds.bottom(), | 1044 region.bounds.bottom(), |
| 1122 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); | 1045 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); |
| 1123 } | 1046 } |
| 1124 return sk_region; | 1047 return sk_region; |
| 1125 } | 1048 } |
| 1126 | 1049 |
| 1127 } // namespace extensions | 1050 } // namespace extensions |
| OLD | NEW |