Remove some ScopedNSAutoreleasePool usage.
This touches a lot of ancient code that trips the presubmit, so skip the presubmit. BUG=772489 Change-Id: Ifea8ca3bd1ebb92eaa47421a6000ae70a25fe3e5 No-Presubmit: true Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1783211 Commit-Queue: Avi Drissman <avi@chromium.org> Reviewed-by: Nico Weber <thakis@chromium.org> Reviewed-by: Elly Fong-Jones <ellyjones@chromium.org> Reviewed-by: Yuwei Huang <yuweih@chromium.org> Reviewed-by: Miguel Casas <mcasas@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org> Cr-Commit-Position: refs/heads/master@{#694364}
This commit is contained in:
base
ios
mac
bind_objc_block_unittest.mmfoundation_util_unittest.mmobjc_release_properties_unittest.mmscoped_nsautorelease_pool.hscoped_nsobject.hscoped_nsobject_unittest.mm
system
test
chrome
app
app_shim
browser
common
test
tools
build
components
content
browser
renderer_host
common
printing
remoting
rlz/mac/lib
services
ui
base
test
views
controls
test
widget
@@ -5,7 +5,6 @@
|
|||||||
#import "base/ios/crb_protocol_observers.h"
|
#import "base/ios/crb_protocol_observers.h"
|
||||||
#include "base/ios/weak_nsobject.h"
|
#include "base/ios/weak_nsobject.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
#include "testing/gtest_mac.h"
|
#include "testing/gtest_mac.h"
|
||||||
@@ -122,11 +121,10 @@ TEST_F(CRBProtocolObserversTest, WeakReference) {
|
|||||||
|
|
||||||
[observers_ addObserver:partial_observer_];
|
[observers_ addObserver:partial_observer_];
|
||||||
|
|
||||||
{
|
// Need an autorelease pool here, because
|
||||||
// Need an autorelease pool here, because
|
// -[CRBProtocolObservers forwardInvocation:] creates a temporary
|
||||||
// -[CRBProtocolObservers forwardInvocation:] creates a temporary
|
// autoreleased array that holds all the observers.
|
||||||
// autoreleased array that holds all the observers.
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
[observers_ requiredMethod];
|
[observers_ requiredMethod];
|
||||||
EXPECT_TRUE([partial_observer_ requiredMethodInvoked]);
|
EXPECT_TRUE([partial_observer_ requiredMethodInvoked]);
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include "base/ios/weak_nsobject.h"
|
#include "base/ios/weak_nsobject.h"
|
||||||
|
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -34,23 +33,24 @@ WeakContainer::~WeakContainer() {}
|
|||||||
+ (scoped_refptr<base::WeakContainer>)containerForObject:(id)object {
|
+ (scoped_refptr<base::WeakContainer>)containerForObject:(id)object {
|
||||||
if (object == nil)
|
if (object == nil)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
// The autoreleasePool is needed here as the call to objc_getAssociatedObject
|
// The autoreleasepool is needed here as the call to objc_getAssociatedObject
|
||||||
// returns an autoreleased object which is better released sooner than later.
|
// returns an autoreleased object which is better released sooner than later.
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
CRBWeakNSProtocolSentinel* sentinel =
|
CRBWeakNSProtocolSentinel* sentinel =
|
||||||
objc_getAssociatedObject(object, &sentinelObserverKey_);
|
objc_getAssociatedObject(object, &sentinelObserverKey_);
|
||||||
if (!sentinel) {
|
if (!sentinel) {
|
||||||
base::scoped_nsobject<CRBWeakNSProtocolSentinel> newSentinel(
|
base::scoped_nsobject<CRBWeakNSProtocolSentinel> newSentinel(
|
||||||
[[CRBWeakNSProtocolSentinel alloc]
|
[[CRBWeakNSProtocolSentinel alloc]
|
||||||
initWithContainer:new base::WeakContainer(object)]);
|
initWithContainer:new base::WeakContainer(object)]);
|
||||||
sentinel = newSentinel;
|
sentinel = newSentinel;
|
||||||
objc_setAssociatedObject(object, &sentinelObserverKey_, sentinel,
|
objc_setAssociatedObject(object, &sentinelObserverKey_, sentinel,
|
||||||
OBJC_ASSOCIATION_RETAIN);
|
OBJC_ASSOCIATION_RETAIN);
|
||||||
// The retain count is 2. One retain is due to the alloc, the other to the
|
// The retain count is 2. One retain is due to the alloc, the other to the
|
||||||
// association with the weak object.
|
// association with the weak object.
|
||||||
DCHECK_EQ(2u, [sentinel retainCount]);
|
DCHECK_EQ(2u, [sentinel retainCount]);
|
||||||
|
}
|
||||||
|
return [sentinel container];
|
||||||
}
|
}
|
||||||
return [sentinel container];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithContainer:(scoped_refptr<base::WeakContainer>)container {
|
- (id)initWithContainer:(scoped_refptr<base::WeakContainer>)container {
|
||||||
|
@@ -7,7 +7,6 @@
|
|||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
#include "base/callback_helpers.h"
|
#include "base/callback_helpers.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "build/build_config.h"
|
#include "build/build_config.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
#include "testing/gtest_mac.h"
|
#include "testing/gtest_mac.h"
|
||||||
@@ -108,8 +107,7 @@ TEST(BindObjcBlockTest, TestSixArguments) {
|
|||||||
TEST(BindObjcBlockTest, TestBlockMoveable) {
|
TEST(BindObjcBlockTest, TestBlockMoveable) {
|
||||||
base::OnceClosure c;
|
base::OnceClosure c;
|
||||||
__block BOOL invoked_block = NO;
|
__block BOOL invoked_block = NO;
|
||||||
{
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool autorelease_pool;
|
|
||||||
c = base::BindOnce(base::RetainBlock(^(std::unique_ptr<BOOL> v) {
|
c = base::BindOnce(base::RetainBlock(^(std::unique_ptr<BOOL> v) {
|
||||||
invoked_block = *v;
|
invoked_block = *v;
|
||||||
}),
|
}),
|
||||||
@@ -139,8 +137,7 @@ TEST(BindObjcBlockTest, TestBlockDeallocation) {
|
|||||||
|
|
||||||
TEST(BindObjcBlockTest, TestBlockReleased) {
|
TEST(BindObjcBlockTest, TestBlockReleased) {
|
||||||
base::WeakNSObject<NSObject> weak_nsobject;
|
base::WeakNSObject<NSObject> weak_nsobject;
|
||||||
{
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool autorelease_pool;
|
|
||||||
NSObject* nsobject = [[[NSObject alloc] init] autorelease];
|
NSObject* nsobject = [[[NSObject alloc] init] autorelease];
|
||||||
weak_nsobject.reset(nsobject);
|
weak_nsobject.reset(nsobject);
|
||||||
|
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/format_macros.h"
|
#include "base/format_macros.h"
|
||||||
#include "base/mac/scoped_cftyperef.h"
|
#include "base/mac/scoped_cftyperef.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/stl_util.h"
|
#include "base/stl_util.h"
|
||||||
#include "base/strings/stringprintf.h"
|
#include "base/strings/stringprintf.h"
|
||||||
#include "build/build_config.h"
|
#include "build/build_config.h"
|
||||||
@@ -162,112 +161,107 @@ TEST(FoundationUtilTest, CFCast) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FoundationUtilTest, ObjCCast) {
|
TEST(FoundationUtilTest, ObjCCast) {
|
||||||
ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
id test_array = @[];
|
||||||
|
id test_array_mutable = [NSMutableArray array];
|
||||||
|
id test_data = [NSData data];
|
||||||
|
id test_data_mutable = [NSMutableData dataWithCapacity:10];
|
||||||
|
id test_date = [NSDate date];
|
||||||
|
id test_dict = @{@"meaning" : @42};
|
||||||
|
id test_dict_mutable = [NSMutableDictionary dictionaryWithCapacity:10];
|
||||||
|
id test_number = @42;
|
||||||
|
id test_null = [NSNull null];
|
||||||
|
id test_set = [NSSet setWithObject:@"string object"];
|
||||||
|
id test_set_mutable = [NSMutableSet setWithCapacity:10];
|
||||||
|
id test_str = [NSString string];
|
||||||
|
id test_str_const = @"bonjour";
|
||||||
|
id test_str_mutable = [NSMutableString stringWithCapacity:10];
|
||||||
|
|
||||||
id test_array = @[];
|
// Make sure the allocations of NS types are good.
|
||||||
id test_array_mutable = [NSMutableArray array];
|
EXPECT_TRUE(test_array);
|
||||||
id test_data = [NSData data];
|
EXPECT_TRUE(test_array_mutable);
|
||||||
id test_data_mutable = [NSMutableData dataWithCapacity:10];
|
EXPECT_TRUE(test_data);
|
||||||
id test_date = [NSDate date];
|
EXPECT_TRUE(test_data_mutable);
|
||||||
id test_dict = @{ @"meaning" : @42 };
|
EXPECT_TRUE(test_date);
|
||||||
id test_dict_mutable = [NSMutableDictionary dictionaryWithCapacity:10];
|
EXPECT_TRUE(test_dict);
|
||||||
id test_number = @42;
|
EXPECT_TRUE(test_dict_mutable);
|
||||||
id test_null = [NSNull null];
|
EXPECT_TRUE(test_number);
|
||||||
id test_set = [NSSet setWithObject:@"string object"];
|
EXPECT_TRUE(test_null);
|
||||||
id test_set_mutable = [NSMutableSet setWithCapacity:10];
|
EXPECT_TRUE(test_set);
|
||||||
id test_str = [NSString string];
|
EXPECT_TRUE(test_set_mutable);
|
||||||
id test_str_const = @"bonjour";
|
EXPECT_TRUE(test_str);
|
||||||
id test_str_mutable = [NSMutableString stringWithCapacity:10];
|
EXPECT_TRUE(test_str_const);
|
||||||
|
EXPECT_TRUE(test_str_mutable);
|
||||||
|
|
||||||
// Make sure the allocations of NS types are good.
|
// Casting the id correctly provides the same pointer.
|
||||||
EXPECT_TRUE(test_array);
|
EXPECT_EQ(test_array, ObjCCast<NSArray>(test_array));
|
||||||
EXPECT_TRUE(test_array_mutable);
|
EXPECT_EQ(test_array_mutable, ObjCCast<NSArray>(test_array_mutable));
|
||||||
EXPECT_TRUE(test_data);
|
EXPECT_EQ(test_data, ObjCCast<NSData>(test_data));
|
||||||
EXPECT_TRUE(test_data_mutable);
|
EXPECT_EQ(test_data_mutable, ObjCCast<NSData>(test_data_mutable));
|
||||||
EXPECT_TRUE(test_date);
|
EXPECT_EQ(test_date, ObjCCast<NSDate>(test_date));
|
||||||
EXPECT_TRUE(test_dict);
|
EXPECT_EQ(test_dict, ObjCCast<NSDictionary>(test_dict));
|
||||||
EXPECT_TRUE(test_dict_mutable);
|
EXPECT_EQ(test_dict_mutable, ObjCCast<NSDictionary>(test_dict_mutable));
|
||||||
EXPECT_TRUE(test_number);
|
EXPECT_EQ(test_number, ObjCCast<NSNumber>(test_number));
|
||||||
EXPECT_TRUE(test_null);
|
EXPECT_EQ(test_null, ObjCCast<NSNull>(test_null));
|
||||||
EXPECT_TRUE(test_set);
|
EXPECT_EQ(test_set, ObjCCast<NSSet>(test_set));
|
||||||
EXPECT_TRUE(test_set_mutable);
|
EXPECT_EQ(test_set_mutable, ObjCCast<NSSet>(test_set_mutable));
|
||||||
EXPECT_TRUE(test_str);
|
EXPECT_EQ(test_str, ObjCCast<NSString>(test_str));
|
||||||
EXPECT_TRUE(test_str_const);
|
EXPECT_EQ(test_str_const, ObjCCast<NSString>(test_str_const));
|
||||||
EXPECT_TRUE(test_str_mutable);
|
EXPECT_EQ(test_str_mutable, ObjCCast<NSString>(test_str_mutable));
|
||||||
|
|
||||||
// Casting the id correctly provides the same pointer.
|
// When given an incorrect ObjC cast, provide nil.
|
||||||
EXPECT_EQ(test_array, ObjCCast<NSArray>(test_array));
|
EXPECT_FALSE(ObjCCast<NSString>(test_array));
|
||||||
EXPECT_EQ(test_array_mutable, ObjCCast<NSArray>(test_array_mutable));
|
EXPECT_FALSE(ObjCCast<NSString>(test_array_mutable));
|
||||||
EXPECT_EQ(test_data, ObjCCast<NSData>(test_data));
|
EXPECT_FALSE(ObjCCast<NSString>(test_data));
|
||||||
EXPECT_EQ(test_data_mutable, ObjCCast<NSData>(test_data_mutable));
|
EXPECT_FALSE(ObjCCast<NSString>(test_data_mutable));
|
||||||
EXPECT_EQ(test_date, ObjCCast<NSDate>(test_date));
|
EXPECT_FALSE(ObjCCast<NSSet>(test_date));
|
||||||
EXPECT_EQ(test_dict, ObjCCast<NSDictionary>(test_dict));
|
EXPECT_FALSE(ObjCCast<NSSet>(test_dict));
|
||||||
EXPECT_EQ(test_dict_mutable, ObjCCast<NSDictionary>(test_dict_mutable));
|
EXPECT_FALSE(ObjCCast<NSNumber>(test_dict_mutable));
|
||||||
EXPECT_EQ(test_number, ObjCCast<NSNumber>(test_number));
|
EXPECT_FALSE(ObjCCast<NSNull>(test_number));
|
||||||
EXPECT_EQ(test_null, ObjCCast<NSNull>(test_null));
|
EXPECT_FALSE(ObjCCast<NSDictionary>(test_null));
|
||||||
EXPECT_EQ(test_set, ObjCCast<NSSet>(test_set));
|
EXPECT_FALSE(ObjCCast<NSDictionary>(test_set));
|
||||||
EXPECT_EQ(test_set_mutable, ObjCCast<NSSet>(test_set_mutable));
|
EXPECT_FALSE(ObjCCast<NSDate>(test_set_mutable));
|
||||||
EXPECT_EQ(test_str, ObjCCast<NSString>(test_str));
|
EXPECT_FALSE(ObjCCast<NSData>(test_str));
|
||||||
EXPECT_EQ(test_str_const, ObjCCast<NSString>(test_str_const));
|
EXPECT_FALSE(ObjCCast<NSData>(test_str_const));
|
||||||
EXPECT_EQ(test_str_mutable, ObjCCast<NSString>(test_str_mutable));
|
EXPECT_FALSE(ObjCCast<NSArray>(test_str_mutable));
|
||||||
|
|
||||||
// When given an incorrect ObjC cast, provide nil.
|
// Giving a nil provides a nil.
|
||||||
EXPECT_FALSE(ObjCCast<NSString>(test_array));
|
EXPECT_FALSE(ObjCCast<NSArray>(nil));
|
||||||
EXPECT_FALSE(ObjCCast<NSString>(test_array_mutable));
|
EXPECT_FALSE(ObjCCast<NSData>(nil));
|
||||||
EXPECT_FALSE(ObjCCast<NSString>(test_data));
|
EXPECT_FALSE(ObjCCast<NSDate>(nil));
|
||||||
EXPECT_FALSE(ObjCCast<NSString>(test_data_mutable));
|
EXPECT_FALSE(ObjCCast<NSDictionary>(nil));
|
||||||
EXPECT_FALSE(ObjCCast<NSSet>(test_date));
|
EXPECT_FALSE(ObjCCast<NSNull>(nil));
|
||||||
EXPECT_FALSE(ObjCCast<NSSet>(test_dict));
|
EXPECT_FALSE(ObjCCast<NSNumber>(nil));
|
||||||
EXPECT_FALSE(ObjCCast<NSNumber>(test_dict_mutable));
|
EXPECT_FALSE(ObjCCast<NSSet>(nil));
|
||||||
EXPECT_FALSE(ObjCCast<NSNull>(test_number));
|
EXPECT_FALSE(ObjCCast<NSString>(nil));
|
||||||
EXPECT_FALSE(ObjCCast<NSDictionary>(test_null));
|
|
||||||
EXPECT_FALSE(ObjCCast<NSDictionary>(test_set));
|
|
||||||
EXPECT_FALSE(ObjCCast<NSDate>(test_set_mutable));
|
|
||||||
EXPECT_FALSE(ObjCCast<NSData>(test_str));
|
|
||||||
EXPECT_FALSE(ObjCCast<NSData>(test_str_const));
|
|
||||||
EXPECT_FALSE(ObjCCast<NSArray>(test_str_mutable));
|
|
||||||
|
|
||||||
// Giving a nil provides a nil.
|
// ObjCCastStrict: correct cast results in correct pointer being returned.
|
||||||
EXPECT_FALSE(ObjCCast<NSArray>(nil));
|
EXPECT_EQ(test_array, ObjCCastStrict<NSArray>(test_array));
|
||||||
EXPECT_FALSE(ObjCCast<NSData>(nil));
|
EXPECT_EQ(test_array_mutable, ObjCCastStrict<NSArray>(test_array_mutable));
|
||||||
EXPECT_FALSE(ObjCCast<NSDate>(nil));
|
EXPECT_EQ(test_data, ObjCCastStrict<NSData>(test_data));
|
||||||
EXPECT_FALSE(ObjCCast<NSDictionary>(nil));
|
EXPECT_EQ(test_data_mutable, ObjCCastStrict<NSData>(test_data_mutable));
|
||||||
EXPECT_FALSE(ObjCCast<NSNull>(nil));
|
EXPECT_EQ(test_date, ObjCCastStrict<NSDate>(test_date));
|
||||||
EXPECT_FALSE(ObjCCast<NSNumber>(nil));
|
EXPECT_EQ(test_dict, ObjCCastStrict<NSDictionary>(test_dict));
|
||||||
EXPECT_FALSE(ObjCCast<NSSet>(nil));
|
EXPECT_EQ(test_dict_mutable,
|
||||||
EXPECT_FALSE(ObjCCast<NSString>(nil));
|
ObjCCastStrict<NSDictionary>(test_dict_mutable));
|
||||||
|
EXPECT_EQ(test_number, ObjCCastStrict<NSNumber>(test_number));
|
||||||
|
EXPECT_EQ(test_null, ObjCCastStrict<NSNull>(test_null));
|
||||||
|
EXPECT_EQ(test_set, ObjCCastStrict<NSSet>(test_set));
|
||||||
|
EXPECT_EQ(test_set_mutable, ObjCCastStrict<NSSet>(test_set_mutable));
|
||||||
|
EXPECT_EQ(test_str, ObjCCastStrict<NSString>(test_str));
|
||||||
|
EXPECT_EQ(test_str_const, ObjCCastStrict<NSString>(test_str_const));
|
||||||
|
EXPECT_EQ(test_str_mutable, ObjCCastStrict<NSString>(test_str_mutable));
|
||||||
|
|
||||||
// ObjCCastStrict: correct cast results in correct pointer being returned.
|
// ObjCCastStrict: Giving a nil provides a nil.
|
||||||
EXPECT_EQ(test_array, ObjCCastStrict<NSArray>(test_array));
|
EXPECT_FALSE(ObjCCastStrict<NSArray>(nil));
|
||||||
EXPECT_EQ(test_array_mutable,
|
EXPECT_FALSE(ObjCCastStrict<NSData>(nil));
|
||||||
ObjCCastStrict<NSArray>(test_array_mutable));
|
EXPECT_FALSE(ObjCCastStrict<NSDate>(nil));
|
||||||
EXPECT_EQ(test_data, ObjCCastStrict<NSData>(test_data));
|
EXPECT_FALSE(ObjCCastStrict<NSDictionary>(nil));
|
||||||
EXPECT_EQ(test_data_mutable,
|
EXPECT_FALSE(ObjCCastStrict<NSNull>(nil));
|
||||||
ObjCCastStrict<NSData>(test_data_mutable));
|
EXPECT_FALSE(ObjCCastStrict<NSNumber>(nil));
|
||||||
EXPECT_EQ(test_date, ObjCCastStrict<NSDate>(test_date));
|
EXPECT_FALSE(ObjCCastStrict<NSSet>(nil));
|
||||||
EXPECT_EQ(test_dict, ObjCCastStrict<NSDictionary>(test_dict));
|
EXPECT_FALSE(ObjCCastStrict<NSString>(nil));
|
||||||
EXPECT_EQ(test_dict_mutable,
|
}
|
||||||
ObjCCastStrict<NSDictionary>(test_dict_mutable));
|
|
||||||
EXPECT_EQ(test_number, ObjCCastStrict<NSNumber>(test_number));
|
|
||||||
EXPECT_EQ(test_null, ObjCCastStrict<NSNull>(test_null));
|
|
||||||
EXPECT_EQ(test_set, ObjCCastStrict<NSSet>(test_set));
|
|
||||||
EXPECT_EQ(test_set_mutable,
|
|
||||||
ObjCCastStrict<NSSet>(test_set_mutable));
|
|
||||||
EXPECT_EQ(test_str, ObjCCastStrict<NSString>(test_str));
|
|
||||||
EXPECT_EQ(test_str_const,
|
|
||||||
ObjCCastStrict<NSString>(test_str_const));
|
|
||||||
EXPECT_EQ(test_str_mutable,
|
|
||||||
ObjCCastStrict<NSString>(test_str_mutable));
|
|
||||||
|
|
||||||
// ObjCCastStrict: Giving a nil provides a nil.
|
|
||||||
EXPECT_FALSE(ObjCCastStrict<NSArray>(nil));
|
|
||||||
EXPECT_FALSE(ObjCCastStrict<NSData>(nil));
|
|
||||||
EXPECT_FALSE(ObjCCastStrict<NSDate>(nil));
|
|
||||||
EXPECT_FALSE(ObjCCastStrict<NSDictionary>(nil));
|
|
||||||
EXPECT_FALSE(ObjCCastStrict<NSNull>(nil));
|
|
||||||
EXPECT_FALSE(ObjCCastStrict<NSNumber>(nil));
|
|
||||||
EXPECT_FALSE(ObjCCastStrict<NSSet>(nil));
|
|
||||||
EXPECT_FALSE(ObjCCastStrict<NSString>(nil));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FoundationUtilTest, GetValueFromDictionary) {
|
TEST(FoundationUtilTest, GetValueFromDictionary) {
|
||||||
|
@@ -5,7 +5,6 @@
|
|||||||
#include "base/mac/objc_release_properties.h"
|
#include "base/mac/objc_release_properties.h"
|
||||||
#include "base/stl_util.h"
|
#include "base/stl_util.h"
|
||||||
|
|
||||||
#import "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
#import <objc/runtime.h>
|
#import <objc/runtime.h>
|
||||||
@@ -268,9 +267,7 @@ TEST(ObjCReleasePropertiesTest, SesameStreet) {
|
|||||||
// Make sure that worked before things get more involved.
|
// Make sure that worked before things get more involved.
|
||||||
EXPECT_EQ(3, ah_ah_ah);
|
EXPECT_EQ(3, ah_ah_ah);
|
||||||
|
|
||||||
{
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
|
|
||||||
test_object.baseCvcRetain = [CountVonCount countVonCount];
|
test_object.baseCvcRetain = [CountVonCount countVonCount];
|
||||||
test_object.baseCvcCopy = [CountVonCount countVonCount];
|
test_object.baseCvcCopy = [CountVonCount countVonCount];
|
||||||
test_object.baseCvcAssign = baseAssign;
|
test_object.baseCvcAssign = baseAssign;
|
||||||
@@ -324,9 +321,7 @@ TEST(ObjCReleasePropertiesTest, SesameStreet) {
|
|||||||
// readonly.
|
// readonly.
|
||||||
EXPECT_EQ(6, ah_ah_ah);
|
EXPECT_EQ(6, ah_ah_ah);
|
||||||
|
|
||||||
{
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
|
|
||||||
// Put things back to how they were.
|
// Put things back to how they were.
|
||||||
test_object.baseCvcRetain = [CountVonCount countVonCount];
|
test_object.baseCvcRetain = [CountVonCount countVonCount];
|
||||||
test_object.baseCvcCopy = [CountVonCount countVonCount];
|
test_object.baseCvcCopy = [CountVonCount countVonCount];
|
||||||
|
@@ -21,6 +21,8 @@ namespace mac {
|
|||||||
// sends it a -drain message when destroyed. This allows an autorelease pool to
|
// sends it a -drain message when destroyed. This allows an autorelease pool to
|
||||||
// be maintained in ordinary C++ code without bringing in any direct Objective-C
|
// be maintained in ordinary C++ code without bringing in any direct Objective-C
|
||||||
// dependency.
|
// dependency.
|
||||||
|
//
|
||||||
|
// Use only in C++ code; use @autoreleasepool in Obj-C(++) code.
|
||||||
|
|
||||||
class BASE_EXPORT ScopedNSAutoreleasePool {
|
class BASE_EXPORT ScopedNSAutoreleasePool {
|
||||||
public:
|
public:
|
||||||
|
@@ -36,11 +36,10 @@ namespace base {
|
|||||||
// scoped_nsprotocol<> has the same behavior as scoped_nsobject, but can be used
|
// scoped_nsprotocol<> has the same behavior as scoped_nsobject, but can be used
|
||||||
// with protocols.
|
// with protocols.
|
||||||
//
|
//
|
||||||
// scoped_nsobject<> is not to be used for NSAutoreleasePools. For
|
// scoped_nsobject<> is not to be used for NSAutoreleasePools. For C++ code use
|
||||||
// NSAutoreleasePools use ScopedNSAutoreleasePool from
|
// NSAutoreleasePool; for Objective-C(++) code use @autoreleasepool instead. We
|
||||||
// scoped_nsautorelease_pool.h instead.
|
// check for bad uses of scoped_nsobject and NSAutoreleasePool at compile time
|
||||||
// We check for bad uses of scoped_nsobject and NSAutoreleasePool at compile
|
// with a template specialization (see below).
|
||||||
// time with a template specialization (see below).
|
|
||||||
//
|
//
|
||||||
// If Automatic Reference Counting (aka ARC) is enabled then the ownership
|
// If Automatic Reference Counting (aka ARC) is enabled then the ownership
|
||||||
// policy is not controllable by the user as ARC make it really difficult to
|
// policy is not controllable by the user as ARC make it really difficult to
|
||||||
@@ -187,7 +186,7 @@ class scoped_nsobject : public scoped_nsprotocol<NST*> {
|
|||||||
|
|
||||||
#if !defined(__has_feature) || !__has_feature(objc_arc)
|
#if !defined(__has_feature) || !__has_feature(objc_arc)
|
||||||
static_assert(std::is_same<NST, NSAutoreleasePool>::value == false,
|
static_assert(std::is_same<NST, NSAutoreleasePool>::value == false,
|
||||||
"Use ScopedNSAutoreleasePool instead");
|
"Use @autoreleasepool instead");
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
@@ -24,8 +23,7 @@ TEST(ScopedNSObjectTest, ScopedNSObject) {
|
|||||||
base::scoped_nsobject<NSObject> p3 = p1;
|
base::scoped_nsobject<NSObject> p3 = p1;
|
||||||
ASSERT_EQ(p1.get(), p3.get());
|
ASSERT_EQ(p1.get(), p3.get());
|
||||||
ASSERT_EQ(2u, [p1 retainCount]);
|
ASSERT_EQ(2u, [p1 retainCount]);
|
||||||
{
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
p3 = p1;
|
p3 = p1;
|
||||||
}
|
}
|
||||||
ASSERT_EQ(p1.get(), p3.get());
|
ASSERT_EQ(p1.get(), p3.get());
|
||||||
@@ -46,8 +44,7 @@ TEST(ScopedNSObjectTest, ScopedNSObject) {
|
|||||||
|
|
||||||
base::scoped_nsobject<NSObject> p6 = p1;
|
base::scoped_nsobject<NSObject> p6 = p1;
|
||||||
ASSERT_EQ(3u, [p6 retainCount]);
|
ASSERT_EQ(3u, [p6 retainCount]);
|
||||||
{
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
p6.autorelease();
|
p6.autorelease();
|
||||||
ASSERT_EQ(nil, p6.get());
|
ASSERT_EQ(nil, p6.get());
|
||||||
ASSERT_EQ(3u, [p1 retainCount]);
|
ASSERT_EQ(3u, [p1 retainCount]);
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/mac/scoped_mach_port.h"
|
#include "base/mac/scoped_mach_port.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/process/process_metrics.h"
|
#include "base/process/process_metrics.h"
|
||||||
#include "base/stl_util.h"
|
#include "base/stl_util.h"
|
||||||
#include "base/strings/string_util.h"
|
#include "base/strings/string_util.h"
|
||||||
@@ -43,9 +42,10 @@ std::string SysInfo::OperatingSystemName() {
|
|||||||
static dispatch_once_t get_system_name_once;
|
static dispatch_once_t get_system_name_once;
|
||||||
static std::string* system_name;
|
static std::string* system_name;
|
||||||
dispatch_once(&get_system_name_once, ^{
|
dispatch_once(&get_system_name_once, ^{
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
system_name = new std::string(
|
system_name = new std::string(
|
||||||
SysNSStringToUTF8([[UIDevice currentDevice] systemName]));
|
SysNSStringToUTF8([[UIDevice currentDevice] systemName]));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// Examples of returned value: 'iPhone OS' on iPad 5.1.1
|
// Examples of returned value: 'iPhone OS' on iPad 5.1.1
|
||||||
// and iPhone 5.1.1.
|
// and iPhone 5.1.1.
|
||||||
@@ -57,9 +57,10 @@ std::string SysInfo::OperatingSystemVersion() {
|
|||||||
static dispatch_once_t get_system_version_once;
|
static dispatch_once_t get_system_version_once;
|
||||||
static std::string* system_version;
|
static std::string* system_version;
|
||||||
dispatch_once(&get_system_version_once, ^{
|
dispatch_once(&get_system_version_once, ^{
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
system_version = new std::string(
|
system_version = new std::string(
|
||||||
SysNSStringToUTF8([[UIDevice currentDevice] systemVersion]));
|
SysNSStringToUTF8([[UIDevice currentDevice] systemVersion]));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return *system_version;
|
return *system_version;
|
||||||
}
|
}
|
||||||
@@ -68,18 +69,19 @@ std::string SysInfo::OperatingSystemVersion() {
|
|||||||
void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
|
void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
|
||||||
int32_t* minor_version,
|
int32_t* minor_version,
|
||||||
int32_t* bugfix_version) {
|
int32_t* bugfix_version) {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
std::string system_version = OperatingSystemVersion();
|
std::string system_version = OperatingSystemVersion();
|
||||||
if (!system_version.empty()) {
|
if (!system_version.empty()) {
|
||||||
// Try to parse out the version numbers from the string.
|
// Try to parse out the version numbers from the string.
|
||||||
int num_read = sscanf(system_version.c_str(), "%d.%d.%d", major_version,
|
int num_read = sscanf(system_version.c_str(), "%d.%d.%d", major_version,
|
||||||
minor_version, bugfix_version);
|
minor_version, bugfix_version);
|
||||||
if (num_read < 1)
|
if (num_read < 1)
|
||||||
*major_version = 0;
|
*major_version = 0;
|
||||||
if (num_read < 2)
|
if (num_read < 2)
|
||||||
*minor_version = 0;
|
*minor_version = 0;
|
||||||
if (num_read < 3)
|
if (num_read < 3)
|
||||||
*bugfix_version = 0;
|
*bugfix_version = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
// The iOS watchdog timer will kill an app that doesn't spin the main event
|
// The iOS watchdog timer will kill an app that doesn't spin the main event
|
||||||
@@ -22,11 +21,11 @@ class IOSRunLoopListener : public testing::EmptyTestEventListener {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void IOSRunLoopListener::OnTestEnd(const testing::TestInfo& test_info) {
|
void IOSRunLoopListener::OnTestEnd(const testing::TestInfo& test_info) {
|
||||||
base::mac::ScopedNSAutoreleasePool scoped_pool;
|
@autoreleasepool {
|
||||||
|
// At the end of the test, spin the default loop for a moment.
|
||||||
// At the end of the test, spin the default loop for a moment.
|
NSDate* stop_date = [NSDate dateWithTimeIntervalSinceNow:0.001];
|
||||||
NSDate* stop_date = [NSDate dateWithTimeIntervalSinceNow:0.001];
|
[[NSRunLoop currentRunLoop] runUntilDate:stop_date];
|
||||||
[[NSRunLoop currentRunLoop] runUntilDate:stop_date];
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include "base/debug/debugger.h"
|
#include "base/debug/debugger.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
#include "base/message_loop/message_pump.h"
|
#include "base/message_loop/message_pump.h"
|
||||||
#include "base/message_loop/message_pump_default.h"
|
#include "base/message_loop/message_pump_default.h"
|
||||||
@@ -209,10 +208,11 @@ void RunTestsFromIOSApp() {
|
|||||||
static bool ran_hook = false;
|
static bool ran_hook = false;
|
||||||
if (!ran_hook) {
|
if (!ran_hook) {
|
||||||
ran_hook = true;
|
ran_hook = true;
|
||||||
mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
int exit_status = UIApplicationMain(g_argc, g_argv, nil,
|
int exit_status =
|
||||||
@"ChromeUnitTestDelegate");
|
UIApplicationMain(g_argc, g_argv, nil, @"ChromeUnitTestDelegate");
|
||||||
exit(exit_status);
|
exit(exit_status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,7 +12,6 @@
|
|||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#import "base/mac/bundle_locations.h"
|
#import "base/mac/bundle_locations.h"
|
||||||
#import "base/mac/foundation_util.h"
|
#import "base/mac/foundation_util.h"
|
||||||
#import "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
#include "chrome/common/chrome_constants.h"
|
#include "chrome/common/chrome_constants.h"
|
||||||
@@ -20,19 +19,18 @@
|
|||||||
#include "content/public/common/content_paths.h"
|
#include "content/public/common/content_paths.h"
|
||||||
|
|
||||||
void SetUpBundleOverrides() {
|
void SetUpBundleOverrides() {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
base::mac::SetOverrideFrameworkBundlePath(chrome::GetFrameworkBundlePath());
|
||||||
|
|
||||||
base::mac::SetOverrideFrameworkBundlePath(chrome::GetFrameworkBundlePath());
|
NSBundle* base_bundle = chrome::OuterAppBundle();
|
||||||
|
base::mac::SetBaseBundleID([[base_bundle bundleIdentifier] UTF8String]);
|
||||||
|
|
||||||
NSBundle* base_bundle = chrome::OuterAppBundle();
|
base::FilePath child_exe_path =
|
||||||
base::mac::SetBaseBundleID([[base_bundle bundleIdentifier] UTF8String]);
|
chrome::GetFrameworkBundlePath().Append("Helpers").Append(
|
||||||
|
chrome::kHelperProcessExecutablePath);
|
||||||
|
|
||||||
base::FilePath child_exe_path =
|
// On the Mac, the child executable lives at a predefined location within
|
||||||
chrome::GetFrameworkBundlePath()
|
// the app bundle's versioned directory.
|
||||||
.Append("Helpers")
|
base::PathService::Override(content::CHILD_PROCESS_EXE, child_exe_path);
|
||||||
.Append(chrome::kHelperProcessExecutablePath);
|
}
|
||||||
|
|
||||||
// On the Mac, the child executable lives at a predefined location within
|
|
||||||
// the app bundle's versioned directory.
|
|
||||||
base::PathService::Override(content::CHILD_PROCESS_EXE, child_exe_path);
|
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,6 @@
|
|||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/mac/foundation_util.h"
|
#include "base/mac/foundation_util.h"
|
||||||
#import "base/mac/launch_services_util.h"
|
#import "base/mac/launch_services_util.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/process/launch.h"
|
#include "base/process/launch.h"
|
||||||
#include "base/strings/string_number_conversions.h"
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
@@ -38,165 +37,166 @@ int LoadFrameworkAndStart(int argc, char** argv) {
|
|||||||
using base::mac::CFCastStrict;
|
using base::mac::CFCastStrict;
|
||||||
using base::mac::NSToCFCast;
|
using base::mac::NSToCFCast;
|
||||||
|
|
||||||
base::mac::ScopedNSAutoreleasePool scoped_pool;
|
@autoreleasepool {
|
||||||
|
// Get the current main bundle, i.e., that of the app loader that's running.
|
||||||
|
NSBundle* app_bundle = [NSBundle mainBundle];
|
||||||
|
CHECK(app_bundle) << "couldn't get loader bundle";
|
||||||
|
|
||||||
// Get the current main bundle, i.e., that of the app loader that's running.
|
// ** 1: Get path to outer Chrome bundle.
|
||||||
NSBundle* app_bundle = [NSBundle mainBundle];
|
// Get the bundle ID of the browser that created this app bundle.
|
||||||
CHECK(app_bundle) << "couldn't get loader bundle";
|
NSString* cr_bundle_id = base::mac::ObjCCast<NSString>(
|
||||||
|
[app_bundle objectForInfoDictionaryKey:app_mode::kBrowserBundleIDKey]);
|
||||||
|
CHECK(cr_bundle_id) << "couldn't get browser bundle ID";
|
||||||
|
|
||||||
// ** 1: Get path to outer Chrome bundle.
|
// First check if Chrome exists at the last known location.
|
||||||
// Get the bundle ID of the browser that created this app bundle.
|
base::FilePath cr_bundle_path;
|
||||||
NSString* cr_bundle_id = base::mac::ObjCCast<NSString>(
|
NSString* cr_bundle_path_ns =
|
||||||
[app_bundle objectForInfoDictionaryKey:app_mode::kBrowserBundleIDKey]);
|
[CFToNSCast(CFCastStrict<CFStringRef>(CFPreferencesCopyAppValue(
|
||||||
CHECK(cr_bundle_id) << "couldn't get browser bundle ID";
|
NSToCFCast(app_mode::kLastRunAppBundlePathPrefsKey),
|
||||||
|
NSToCFCast(cr_bundle_id)))) autorelease];
|
||||||
|
cr_bundle_path = base::mac::NSStringToFilePath(cr_bundle_path_ns);
|
||||||
|
bool found_bundle =
|
||||||
|
!cr_bundle_path.empty() && base::DirectoryExists(cr_bundle_path);
|
||||||
|
|
||||||
// First check if Chrome exists at the last known location.
|
if (!found_bundle) {
|
||||||
base::FilePath cr_bundle_path;
|
// If no such bundle path exists, try to search by bundle ID.
|
||||||
NSString* cr_bundle_path_ns =
|
if (!app_mode::FindBundleById(cr_bundle_id, &cr_bundle_path)) {
|
||||||
[CFToNSCast(CFCastStrict<CFStringRef>(CFPreferencesCopyAppValue(
|
// TODO(jeremy): Display UI to allow user to manually locate the Chrome
|
||||||
NSToCFCast(app_mode::kLastRunAppBundlePathPrefsKey),
|
// bundle.
|
||||||
NSToCFCast(cr_bundle_id)))) autorelease];
|
LOG(FATAL) << "Failed to locate bundle by identifier";
|
||||||
cr_bundle_path = base::mac::NSStringToFilePath(cr_bundle_path_ns);
|
}
|
||||||
bool found_bundle =
|
|
||||||
!cr_bundle_path.empty() && base::DirectoryExists(cr_bundle_path);
|
|
||||||
|
|
||||||
if (!found_bundle) {
|
|
||||||
// If no such bundle path exists, try to search by bundle ID.
|
|
||||||
if (!app_mode::FindBundleById(cr_bundle_id, &cr_bundle_path)) {
|
|
||||||
// TODO(jeremy): Display UI to allow user to manually locate the Chrome
|
|
||||||
// bundle.
|
|
||||||
LOG(FATAL) << "Failed to locate bundle by identifier";
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// ** 2: Read the running Chrome version.
|
// ** 2: Read the running Chrome version.
|
||||||
// The user_data_dir for shims actually contains the app_data_path.
|
// The user_data_dir for shims actually contains the app_data_path.
|
||||||
// I.e. <user_data_dir>/<profile_dir>/Web Applications/_crx_extensionid/
|
// I.e. <user_data_dir>/<profile_dir>/Web Applications/_crx_extensionid/
|
||||||
base::FilePath app_data_dir = base::mac::NSStringToFilePath([app_bundle
|
base::FilePath app_data_dir = base::mac::NSStringToFilePath([app_bundle
|
||||||
objectForInfoDictionaryKey:app_mode::kCrAppModeUserDataDirKey]);
|
objectForInfoDictionaryKey:app_mode::kCrAppModeUserDataDirKey]);
|
||||||
base::FilePath user_data_dir = app_data_dir.DirName().DirName().DirName();
|
base::FilePath user_data_dir = app_data_dir.DirName().DirName().DirName();
|
||||||
CHECK(!user_data_dir.empty());
|
CHECK(!user_data_dir.empty());
|
||||||
|
|
||||||
// If the version file does not exist, |cr_version_str| will be empty and
|
// If the version file does not exist, |cr_version_str| will be empty and
|
||||||
// app_mode::GetChromeBundleInfo will default to the latest version.
|
// app_mode::GetChromeBundleInfo will default to the latest version.
|
||||||
base::FilePath cr_version_str;
|
base::FilePath cr_version_str;
|
||||||
base::ReadSymbolicLink(
|
base::ReadSymbolicLink(
|
||||||
user_data_dir.Append(app_mode::kRunningChromeVersionSymlinkName),
|
user_data_dir.Append(app_mode::kRunningChromeVersionSymlinkName),
|
||||||
&cr_version_str);
|
&cr_version_str);
|
||||||
|
|
||||||
// If the version file does exist, it may have been left by a crashed Chrome
|
// If the version file does exist, it may have been left by a crashed Chrome
|
||||||
// process. Ensure the process is still running.
|
// process. Ensure the process is still running.
|
||||||
if (!cr_version_str.empty()) {
|
if (!cr_version_str.empty()) {
|
||||||
NSArray* existing_chrome = [NSRunningApplication
|
NSArray* existing_chrome = [NSRunningApplication
|
||||||
runningApplicationsWithBundleIdentifier:cr_bundle_id];
|
runningApplicationsWithBundleIdentifier:cr_bundle_id];
|
||||||
if ([existing_chrome count] == 0)
|
if ([existing_chrome count] == 0)
|
||||||
cr_version_str.clear();
|
cr_version_str.clear();
|
||||||
}
|
|
||||||
|
|
||||||
// ** 3: Read information from the Chrome bundle.
|
|
||||||
base::FilePath executable_path;
|
|
||||||
base::FilePath framework_path;
|
|
||||||
base::FilePath framework_dylib_path;
|
|
||||||
if (!app_mode::GetChromeBundleInfo(cr_bundle_path, cr_version_str.value(),
|
|
||||||
&executable_path, &framework_path,
|
|
||||||
&framework_dylib_path)) {
|
|
||||||
LOG(FATAL) << "Couldn't ready Chrome bundle info";
|
|
||||||
}
|
|
||||||
base::FilePath app_mode_bundle_path =
|
|
||||||
base::mac::NSStringToFilePath([app_bundle bundlePath]);
|
|
||||||
|
|
||||||
// ** 4: Read information from the Info.plist.
|
|
||||||
// Read information about the this app shortcut from the Info.plist.
|
|
||||||
// Don't check for null-ness on optional items.
|
|
||||||
NSDictionary* info_plist = [app_bundle infoDictionary];
|
|
||||||
CHECK(info_plist) << "couldn't get loader Info.plist";
|
|
||||||
|
|
||||||
const std::string app_mode_id = SysNSStringToUTF8(
|
|
||||||
[info_plist objectForKey:app_mode::kCrAppModeShortcutIDKey]);
|
|
||||||
CHECK(app_mode_id.size()) << "couldn't get app shortcut ID";
|
|
||||||
|
|
||||||
const std::string app_mode_name = SysNSStringToUTF8(
|
|
||||||
[info_plist objectForKey:app_mode::kCrAppModeShortcutNameKey]);
|
|
||||||
const std::string app_mode_url = SysNSStringToUTF8(
|
|
||||||
[info_plist objectForKey:app_mode::kCrAppModeShortcutURLKey]);
|
|
||||||
|
|
||||||
base::FilePath plist_user_data_dir = base::mac::NSStringToFilePath(
|
|
||||||
[info_plist objectForKey:app_mode::kCrAppModeUserDataDirKey]);
|
|
||||||
|
|
||||||
base::FilePath profile_dir = base::mac::NSStringToFilePath(
|
|
||||||
[info_plist objectForKey:app_mode::kCrAppModeProfileDirKey]);
|
|
||||||
|
|
||||||
// ** 5: Open the framework.
|
|
||||||
StartFun ChromeAppModeStart = NULL;
|
|
||||||
void* cr_dylib = dlopen(framework_dylib_path.value().c_str(), RTLD_LAZY);
|
|
||||||
if (cr_dylib) {
|
|
||||||
// Find the entry point.
|
|
||||||
ChromeAppModeStart =
|
|
||||||
(StartFun)dlsym(cr_dylib, APP_SHIM_ENTRY_POINT_NAME_STRING);
|
|
||||||
if (!ChromeAppModeStart)
|
|
||||||
LOG(ERROR) << "Couldn't get entry point: " << dlerror();
|
|
||||||
} else {
|
|
||||||
LOG(ERROR) << "Couldn't load framework: " << dlerror();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ** 6: Fill in ChromeAppModeInfo and call into Chrome's framework.
|
|
||||||
if (ChromeAppModeStart) {
|
|
||||||
// Ensure that the strings pointed to by |info| outlive |info|.
|
|
||||||
const std::string framework_path_utf8 = framework_path.AsUTF8Unsafe();
|
|
||||||
const std::string cr_bundle_path_utf8 = cr_bundle_path.AsUTF8Unsafe();
|
|
||||||
const std::string app_mode_bundle_path_utf8 =
|
|
||||||
app_mode_bundle_path.AsUTF8Unsafe();
|
|
||||||
const std::string plist_user_data_dir_utf8 =
|
|
||||||
plist_user_data_dir.AsUTF8Unsafe();
|
|
||||||
const std::string profile_dir_utf8 = profile_dir.AsUTF8Unsafe();
|
|
||||||
app_mode::ChromeAppModeInfo info;
|
|
||||||
info.argc = argc;
|
|
||||||
info.argv = argv;
|
|
||||||
info.chrome_framework_path = framework_path_utf8.c_str();
|
|
||||||
info.chrome_outer_bundle_path = cr_bundle_path_utf8.c_str();
|
|
||||||
info.app_mode_bundle_path = app_mode_bundle_path_utf8.c_str();
|
|
||||||
info.app_mode_id = app_mode_id.c_str();
|
|
||||||
info.app_mode_name = app_mode_name.c_str();
|
|
||||||
info.app_mode_url = app_mode_url.c_str();
|
|
||||||
info.user_data_dir = plist_user_data_dir_utf8.c_str();
|
|
||||||
info.profile_dir = profile_dir_utf8.c_str();
|
|
||||||
return ChromeAppModeStart(&info);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(ERROR) << "Loading Chrome failed, launching Chrome with command line";
|
|
||||||
base::CommandLine command_line(executable_path);
|
|
||||||
// The user_data_dir from the plist is actually the app data dir.
|
|
||||||
command_line.AppendSwitchPath(
|
|
||||||
switches::kUserDataDir,
|
|
||||||
plist_user_data_dir.DirName().DirName().DirName());
|
|
||||||
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
|
||||||
app_mode::kLaunchedByChromeProcessId)) {
|
|
||||||
// Pass --app-shim-error to have Chrome rebuild this shim.
|
|
||||||
// If Chrome has rebuilt this shim once already, then rebuilding doesn't fix
|
|
||||||
// the problem, so don't try again.
|
|
||||||
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
|
||||||
app_mode::kLaunchedAfterRebuild)) {
|
|
||||||
command_line.AppendSwitchPath(app_mode::kAppShimError,
|
|
||||||
app_mode_bundle_path);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// If the shim was launched directly (instead of by Chrome), first ask
|
|
||||||
// Chrome to launch the app. Chrome will launch the shim again, the same
|
|
||||||
// error will occur and be handled above. This approach allows the app to be
|
|
||||||
// started without blocking on fixing the shim and guarantees that the
|
|
||||||
// profile is loaded when Chrome receives --app-shim-error.
|
|
||||||
command_line.AppendSwitchPath(switches::kProfileDirectory, profile_dir);
|
|
||||||
command_line.AppendSwitchASCII(switches::kAppId, app_mode_id);
|
|
||||||
}
|
|
||||||
// Launch the executable directly since base::mac::OpenApplicationWithPath
|
|
||||||
// doesn't pass command line arguments if the application is already running.
|
|
||||||
if (!base::LaunchProcess(command_line, base::LaunchOptions()).IsValid()) {
|
|
||||||
LOG(ERROR) << "Could not launch Chrome: "
|
|
||||||
<< command_line.GetCommandLineString();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
// ** 3: Read information from the Chrome bundle.
|
||||||
|
base::FilePath executable_path;
|
||||||
|
base::FilePath framework_path;
|
||||||
|
base::FilePath framework_dylib_path;
|
||||||
|
if (!app_mode::GetChromeBundleInfo(cr_bundle_path, cr_version_str.value(),
|
||||||
|
&executable_path, &framework_path,
|
||||||
|
&framework_dylib_path)) {
|
||||||
|
LOG(FATAL) << "Couldn't ready Chrome bundle info";
|
||||||
|
}
|
||||||
|
base::FilePath app_mode_bundle_path =
|
||||||
|
base::mac::NSStringToFilePath([app_bundle bundlePath]);
|
||||||
|
|
||||||
|
// ** 4: Read information from the Info.plist.
|
||||||
|
// Read information about the this app shortcut from the Info.plist.
|
||||||
|
// Don't check for null-ness on optional items.
|
||||||
|
NSDictionary* info_plist = [app_bundle infoDictionary];
|
||||||
|
CHECK(info_plist) << "couldn't get loader Info.plist";
|
||||||
|
|
||||||
|
const std::string app_mode_id = SysNSStringToUTF8(
|
||||||
|
[info_plist objectForKey:app_mode::kCrAppModeShortcutIDKey]);
|
||||||
|
CHECK(app_mode_id.size()) << "couldn't get app shortcut ID";
|
||||||
|
|
||||||
|
const std::string app_mode_name = SysNSStringToUTF8(
|
||||||
|
[info_plist objectForKey:app_mode::kCrAppModeShortcutNameKey]);
|
||||||
|
const std::string app_mode_url = SysNSStringToUTF8(
|
||||||
|
[info_plist objectForKey:app_mode::kCrAppModeShortcutURLKey]);
|
||||||
|
|
||||||
|
base::FilePath plist_user_data_dir = base::mac::NSStringToFilePath(
|
||||||
|
[info_plist objectForKey:app_mode::kCrAppModeUserDataDirKey]);
|
||||||
|
|
||||||
|
base::FilePath profile_dir = base::mac::NSStringToFilePath(
|
||||||
|
[info_plist objectForKey:app_mode::kCrAppModeProfileDirKey]);
|
||||||
|
|
||||||
|
// ** 5: Open the framework.
|
||||||
|
StartFun ChromeAppModeStart = NULL;
|
||||||
|
void* cr_dylib = dlopen(framework_dylib_path.value().c_str(), RTLD_LAZY);
|
||||||
|
if (cr_dylib) {
|
||||||
|
// Find the entry point.
|
||||||
|
ChromeAppModeStart =
|
||||||
|
(StartFun)dlsym(cr_dylib, APP_SHIM_ENTRY_POINT_NAME_STRING);
|
||||||
|
if (!ChromeAppModeStart)
|
||||||
|
LOG(ERROR) << "Couldn't get entry point: " << dlerror();
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "Couldn't load framework: " << dlerror();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ** 6: Fill in ChromeAppModeInfo and call into Chrome's framework.
|
||||||
|
if (ChromeAppModeStart) {
|
||||||
|
// Ensure that the strings pointed to by |info| outlive |info|.
|
||||||
|
const std::string framework_path_utf8 = framework_path.AsUTF8Unsafe();
|
||||||
|
const std::string cr_bundle_path_utf8 = cr_bundle_path.AsUTF8Unsafe();
|
||||||
|
const std::string app_mode_bundle_path_utf8 =
|
||||||
|
app_mode_bundle_path.AsUTF8Unsafe();
|
||||||
|
const std::string plist_user_data_dir_utf8 =
|
||||||
|
plist_user_data_dir.AsUTF8Unsafe();
|
||||||
|
const std::string profile_dir_utf8 = profile_dir.AsUTF8Unsafe();
|
||||||
|
app_mode::ChromeAppModeInfo info;
|
||||||
|
info.argc = argc;
|
||||||
|
info.argv = argv;
|
||||||
|
info.chrome_framework_path = framework_path_utf8.c_str();
|
||||||
|
info.chrome_outer_bundle_path = cr_bundle_path_utf8.c_str();
|
||||||
|
info.app_mode_bundle_path = app_mode_bundle_path_utf8.c_str();
|
||||||
|
info.app_mode_id = app_mode_id.c_str();
|
||||||
|
info.app_mode_name = app_mode_name.c_str();
|
||||||
|
info.app_mode_url = app_mode_url.c_str();
|
||||||
|
info.user_data_dir = plist_user_data_dir_utf8.c_str();
|
||||||
|
info.profile_dir = profile_dir_utf8.c_str();
|
||||||
|
return ChromeAppModeStart(&info);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(ERROR) << "Loading Chrome failed, launching Chrome with command line";
|
||||||
|
base::CommandLine command_line(executable_path);
|
||||||
|
// The user_data_dir from the plist is actually the app data dir.
|
||||||
|
command_line.AppendSwitchPath(
|
||||||
|
switches::kUserDataDir,
|
||||||
|
plist_user_data_dir.DirName().DirName().DirName());
|
||||||
|
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||||
|
app_mode::kLaunchedByChromeProcessId)) {
|
||||||
|
// Pass --app-shim-error to have Chrome rebuild this shim.
|
||||||
|
// If Chrome has rebuilt this shim once already, then rebuilding doesn't
|
||||||
|
// fix the problem, so don't try again.
|
||||||
|
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||||
|
app_mode::kLaunchedAfterRebuild)) {
|
||||||
|
command_line.AppendSwitchPath(app_mode::kAppShimError,
|
||||||
|
app_mode_bundle_path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If the shim was launched directly (instead of by Chrome), first ask
|
||||||
|
// Chrome to launch the app. Chrome will launch the shim again, the same
|
||||||
|
// error will occur and be handled above. This approach allows the app to
|
||||||
|
// be started without blocking on fixing the shim and guarantees that the
|
||||||
|
// profile is loaded when Chrome receives --app-shim-error.
|
||||||
|
command_line.AppendSwitchPath(switches::kProfileDirectory, profile_dir);
|
||||||
|
command_line.AppendSwitchASCII(switches::kAppId, app_mode_id);
|
||||||
|
}
|
||||||
|
// Launch the executable directly since base::mac::OpenApplicationWithPath
|
||||||
|
// doesn't pass command line arguments if the application is already
|
||||||
|
// running.
|
||||||
|
if (!base::LaunchProcess(command_line, base::LaunchOptions()).IsValid()) {
|
||||||
|
LOG(ERROR) << "Could not launch Chrome: "
|
||||||
|
<< command_line.GetCommandLineString();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -18,7 +18,6 @@
|
|||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/mac/bundle_locations.h"
|
#include "base/mac/bundle_locations.h"
|
||||||
#include "base/mac/mac_logging.h"
|
#include "base/mac/mac_logging.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "base/message_loop/message_pump_type.h"
|
#include "base/message_loop/message_pump_type.h"
|
||||||
#include "base/run_loop.h"
|
#include "base/run_loop.h"
|
||||||
@@ -73,94 +72,96 @@ void PostRepeatingDelayedTask() {
|
|||||||
int APP_SHIM_ENTRY_POINT_NAME(const app_mode::ChromeAppModeInfo* info) {
|
int APP_SHIM_ENTRY_POINT_NAME(const app_mode::ChromeAppModeInfo* info) {
|
||||||
base::CommandLine::Init(info->argc, info->argv);
|
base::CommandLine::Init(info->argc, info->argv);
|
||||||
|
|
||||||
base::mac::ScopedNSAutoreleasePool scoped_pool;
|
@autoreleasepool {
|
||||||
base::AtExitManager exit_manager;
|
base::AtExitManager exit_manager;
|
||||||
chrome::RegisterPathProvider();
|
chrome::RegisterPathProvider();
|
||||||
|
|
||||||
// Set bundle paths. This loads the bundles.
|
// Set bundle paths. This loads the bundles.
|
||||||
base::mac::SetOverrideOuterBundlePath(
|
base::mac::SetOverrideOuterBundlePath(
|
||||||
base::FilePath(info->chrome_outer_bundle_path));
|
base::FilePath(info->chrome_outer_bundle_path));
|
||||||
base::mac::SetOverrideFrameworkBundlePath(
|
base::mac::SetOverrideFrameworkBundlePath(
|
||||||
base::FilePath(info->chrome_framework_path));
|
base::FilePath(info->chrome_framework_path));
|
||||||
|
|
||||||
ChromeCrashReporterClient::Create();
|
ChromeCrashReporterClient::Create();
|
||||||
crash_reporter::InitializeCrashpad(true, "app_shim");
|
crash_reporter::InitializeCrashpad(true, "app_shim");
|
||||||
|
|
||||||
// Calculate the preferred locale used by Chrome.
|
// Calculate the preferred locale used by Chrome. We can't use
|
||||||
// We can't use l10n_util::OverrideLocaleWithCocoaLocale() because it calls
|
// l10n_util::OverrideLocaleWithCocoaLocale() because it calls
|
||||||
// [base::mac::OuterBundle() preferredLocalizations] which gets localizations
|
// [base::mac::OuterBundle() preferredLocalizations] which gets
|
||||||
// from the bundle of the running app (i.e. it is equivalent to
|
// localizations from the bundle of the running app (i.e. it is equivalent
|
||||||
// [[NSBundle mainBundle] preferredLocalizations]) instead of the target
|
// to [[NSBundle mainBundle] preferredLocalizations]) instead of the target
|
||||||
// bundle.
|
// bundle.
|
||||||
NSArray* preferred_languages = [NSLocale preferredLanguages];
|
NSArray* preferred_languages = [NSLocale preferredLanguages];
|
||||||
NSArray* supported_languages = [base::mac::OuterBundle() localizations];
|
NSArray* supported_languages = [base::mac::OuterBundle() localizations];
|
||||||
std::string preferred_localization;
|
std::string preferred_localization;
|
||||||
for (NSString* language in preferred_languages) {
|
for (NSString* language in preferred_languages) {
|
||||||
// We must convert the "-" separator to "_" to be compatible with
|
// We must convert the "-" separator to "_" to be compatible with
|
||||||
// NSBundle::localizations() e.g. "en-GB" becomes "en_GB".
|
// NSBundle::localizations() e.g. "en-GB" becomes "en_GB".
|
||||||
// See https://crbug.com/913345.
|
// See https://crbug.com/913345.
|
||||||
language = [language stringByReplacingOccurrencesOfString:@"-"
|
language = [language stringByReplacingOccurrencesOfString:@"-"
|
||||||
withString:@"_"];
|
withString:@"_"];
|
||||||
if ([supported_languages containsObject:language]) {
|
if ([supported_languages containsObject:language]) {
|
||||||
preferred_localization = base::SysNSStringToUTF8(language);
|
preferred_localization = base::SysNSStringToUTF8(language);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Check for language support without the region component.
|
// Check for language support without the region component.
|
||||||
language = [language componentsSeparatedByString:@"_"][0];
|
language = [language componentsSeparatedByString:@"_"][0];
|
||||||
if ([supported_languages containsObject:language]) {
|
if ([supported_languages containsObject:language]) {
|
||||||
preferred_localization = base::SysNSStringToUTF8(language);
|
preferred_localization = base::SysNSStringToUTF8(language);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
std::string locale = l10n_util::NormalizeLocale(
|
||||||
|
l10n_util::GetApplicationLocale(preferred_localization));
|
||||||
|
|
||||||
|
// Load localized strings and mouse cursor images.
|
||||||
|
ui::ResourceBundle::InitSharedInstanceWithLocale(
|
||||||
|
locale, NULL, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
|
||||||
|
|
||||||
|
ChromeContentClient chrome_content_client;
|
||||||
|
content::SetContentClient(&chrome_content_client);
|
||||||
|
|
||||||
|
// Launch the IO thread.
|
||||||
|
base::Thread::Options io_thread_options;
|
||||||
|
io_thread_options.message_pump_type = base::MessagePumpType::IO;
|
||||||
|
base::Thread* io_thread = new base::Thread("CrAppShimIO");
|
||||||
|
io_thread->StartWithOptions(io_thread_options);
|
||||||
|
|
||||||
|
mojo::core::Init();
|
||||||
|
mojo::core::ScopedIPCSupport ipc_support(
|
||||||
|
io_thread->task_runner(),
|
||||||
|
mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);
|
||||||
|
|
||||||
|
// Initialize the NSApplication (and ensure that it was not previously
|
||||||
|
// initialized).
|
||||||
|
[AppShimApplication sharedApplication];
|
||||||
|
CHECK([NSApp isKindOfClass:[AppShimApplication class]]);
|
||||||
|
|
||||||
|
base::SingleThreadTaskExecutor main_task_executor(
|
||||||
|
base::MessagePumpType::UI);
|
||||||
|
ui::WindowResizeHelperMac::Get()->Init(main_task_executor.task_runner());
|
||||||
|
base::PlatformThread::SetName("CrAppShimMain");
|
||||||
|
|
||||||
|
// TODO(https://crbug.com/925998): This workaround ensures that there is
|
||||||
|
// always delayed work enqueued. If there is ever not enqueued delayed work,
|
||||||
|
// then NSMenus and NSAlerts can start misbehaving (see
|
||||||
|
// https://crbug.com/920795 for examples). This workaround is not an
|
||||||
|
// appropriate solution to the problem, and should be replaced by a fix in
|
||||||
|
// the relevant message pump code.
|
||||||
|
PostRepeatingDelayedTask();
|
||||||
|
|
||||||
|
AppShimController::Params controller_params;
|
||||||
|
// Note that |info->user_data_dir| for shims contains the app data path,
|
||||||
|
// <user_data_dir>/<profile_dir>/Web Applications/_crx_extensionid/.
|
||||||
|
controller_params.user_data_dir =
|
||||||
|
base::FilePath(info->user_data_dir).DirName().DirName().DirName();
|
||||||
|
controller_params.profile_dir = base::FilePath(info->profile_dir);
|
||||||
|
controller_params.app_id = info->app_mode_id;
|
||||||
|
controller_params.app_name = base::UTF8ToUTF16(info->app_mode_name);
|
||||||
|
controller_params.app_url = GURL(info->app_mode_url);
|
||||||
|
|
||||||
|
AppShimController controller(controller_params);
|
||||||
|
base::RunLoop().Run();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
std::string locale = l10n_util::NormalizeLocale(
|
|
||||||
l10n_util::GetApplicationLocale(preferred_localization));
|
|
||||||
|
|
||||||
// Load localized strings and mouse cursor images.
|
|
||||||
ui::ResourceBundle::InitSharedInstanceWithLocale(
|
|
||||||
locale, NULL, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
|
|
||||||
|
|
||||||
ChromeContentClient chrome_content_client;
|
|
||||||
content::SetContentClient(&chrome_content_client);
|
|
||||||
|
|
||||||
// Launch the IO thread.
|
|
||||||
base::Thread::Options io_thread_options;
|
|
||||||
io_thread_options.message_pump_type = base::MessagePumpType::IO;
|
|
||||||
base::Thread *io_thread = new base::Thread("CrAppShimIO");
|
|
||||||
io_thread->StartWithOptions(io_thread_options);
|
|
||||||
|
|
||||||
mojo::core::Init();
|
|
||||||
mojo::core::ScopedIPCSupport ipc_support(
|
|
||||||
io_thread->task_runner(),
|
|
||||||
mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);
|
|
||||||
|
|
||||||
// Initialize the NSApplication (and ensure that it was not previously
|
|
||||||
// initialized).
|
|
||||||
[AppShimApplication sharedApplication];
|
|
||||||
CHECK([NSApp isKindOfClass:[AppShimApplication class]]);
|
|
||||||
|
|
||||||
base::SingleThreadTaskExecutor main_task_executor(base::MessagePumpType::UI);
|
|
||||||
ui::WindowResizeHelperMac::Get()->Init(main_task_executor.task_runner());
|
|
||||||
base::PlatformThread::SetName("CrAppShimMain");
|
|
||||||
|
|
||||||
// TODO(https://crbug.com/925998): This workaround ensures that there is
|
|
||||||
// always delayed work enqueued. If there is ever not enqueued delayed work,
|
|
||||||
// then NSMenus and NSAlerts can start misbehaving (see
|
|
||||||
// https://crbug.com/920795 for examples). This workaround is not an
|
|
||||||
// appropriate solution to the problem, and should be replaced by a fix in
|
|
||||||
// the relevant message pump code.
|
|
||||||
PostRepeatingDelayedTask();
|
|
||||||
|
|
||||||
AppShimController::Params controller_params;
|
|
||||||
// Note that |info->user_data_dir| for shims contains the app data path,
|
|
||||||
// <user_data_dir>/<profile_dir>/Web Applications/_crx_extensionid/.
|
|
||||||
controller_params.user_data_dir =
|
|
||||||
base::FilePath(info->user_data_dir).DirName().DirName().DirName();
|
|
||||||
controller_params.profile_dir = base::FilePath(info->profile_dir);
|
|
||||||
controller_params.app_id = info->app_mode_id;
|
|
||||||
controller_params.app_name = base::UTF8ToUTF16(info->app_mode_name);
|
|
||||||
controller_params.app_url = GURL(info->app_mode_url);
|
|
||||||
|
|
||||||
AppShimController controller(controller_params);
|
|
||||||
base::RunLoop().Run();
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,6 @@
|
|||||||
#include "base/mac/scoped_authorizationref.h"
|
#include "base/mac/scoped_authorizationref.h"
|
||||||
#include "base/mac/scoped_cftyperef.h"
|
#include "base/mac/scoped_cftyperef.h"
|
||||||
#include "base/mac/scoped_ioobject.h"
|
#include "base/mac/scoped_ioobject.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/mac/sdk_forward_declarations.h"
|
#include "base/mac/sdk_forward_declarations.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "base/stl_util.h"
|
#include "base/stl_util.h"
|
||||||
@@ -407,84 +406,80 @@ DiskImageStatus IsAppRunningFromReadOnlyDiskImage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MaybeInstallFromDiskImage() {
|
bool MaybeInstallFromDiskImage() {
|
||||||
base::mac::ScopedNSAutoreleasePool autorelease_pool;
|
@autoreleasepool {
|
||||||
|
std::string dmg_bsd_device_name;
|
||||||
|
if (IsAppRunningFromReadOnlyDiskImage(&dmg_bsd_device_name) !=
|
||||||
|
DiskImageStatusTrue) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::string dmg_bsd_device_name;
|
NSArray* application_directories = NSSearchPathForDirectoriesInDomains(
|
||||||
if (IsAppRunningFromReadOnlyDiskImage(&dmg_bsd_device_name) !=
|
NSApplicationDirectory, NSLocalDomainMask, YES);
|
||||||
DiskImageStatusTrue) {
|
if ([application_directories count] == 0) {
|
||||||
return false;
|
LOG(ERROR) << "NSSearchPathForDirectoriesInDomains: "
|
||||||
|
<< "no local application directories";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
NSString* application_directory = [application_directories objectAtIndex:0];
|
||||||
|
|
||||||
|
NSFileManager* file_manager = [NSFileManager defaultManager];
|
||||||
|
|
||||||
|
BOOL is_directory;
|
||||||
|
if (![file_manager fileExistsAtPath:application_directory
|
||||||
|
isDirectory:&is_directory] ||
|
||||||
|
!is_directory) {
|
||||||
|
VLOG(1) << "No application directory at "
|
||||||
|
<< [application_directory UTF8String];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString* source_path = [base::mac::OuterBundle() bundlePath];
|
||||||
|
NSString* application_name = [source_path lastPathComponent];
|
||||||
|
NSString* target_path =
|
||||||
|
[application_directory stringByAppendingPathComponent:application_name];
|
||||||
|
|
||||||
|
if ([file_manager fileExistsAtPath:target_path]) {
|
||||||
|
VLOG(1) << "Something already exists at " << [target_path UTF8String];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString* installer_path =
|
||||||
|
[base::mac::FrameworkBundle() pathForResource:@"install" ofType:@"sh"];
|
||||||
|
if (!installer_path) {
|
||||||
|
VLOG(1) << "Could not locate install.sh";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ShouldInstallDialog()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
base::mac::ScopedAuthorizationRef authorization(
|
||||||
|
MaybeShowAuthorizationDialog(application_directory));
|
||||||
|
// authorization will be NULL if it's deemed unnecessary or if
|
||||||
|
// authentication fails. In either case, try to install without privilege
|
||||||
|
// escalation.
|
||||||
|
|
||||||
|
if (!InstallFromDiskImage(authorization.release(), installer_path,
|
||||||
|
source_path, target_path)) {
|
||||||
|
ShowErrorDialog();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dock::AddIcon(target_path, source_path);
|
||||||
|
|
||||||
|
if (dmg_bsd_device_name.empty()) {
|
||||||
|
// Not fatal, just diagnostic.
|
||||||
|
LOG(ERROR) << "Could not determine disk image BSD device name";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!LaunchInstalledApp(target_path, dmg_bsd_device_name)) {
|
||||||
|
ShowErrorDialog();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSArray* application_directories =
|
|
||||||
NSSearchPathForDirectoriesInDomains(NSApplicationDirectory,
|
|
||||||
NSLocalDomainMask,
|
|
||||||
YES);
|
|
||||||
if ([application_directories count] == 0) {
|
|
||||||
LOG(ERROR) << "NSSearchPathForDirectoriesInDomains: "
|
|
||||||
<< "no local application directories";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
NSString* application_directory = [application_directories objectAtIndex:0];
|
|
||||||
|
|
||||||
NSFileManager* file_manager = [NSFileManager defaultManager];
|
|
||||||
|
|
||||||
BOOL is_directory;
|
|
||||||
if (![file_manager fileExistsAtPath:application_directory
|
|
||||||
isDirectory:&is_directory] ||
|
|
||||||
!is_directory) {
|
|
||||||
VLOG(1) << "No application directory at "
|
|
||||||
<< [application_directory UTF8String];
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString* source_path = [base::mac::OuterBundle() bundlePath];
|
|
||||||
NSString* application_name = [source_path lastPathComponent];
|
|
||||||
NSString* target_path =
|
|
||||||
[application_directory stringByAppendingPathComponent:application_name];
|
|
||||||
|
|
||||||
if ([file_manager fileExistsAtPath:target_path]) {
|
|
||||||
VLOG(1) << "Something already exists at " << [target_path UTF8String];
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString* installer_path =
|
|
||||||
[base::mac::FrameworkBundle() pathForResource:@"install" ofType:@"sh"];
|
|
||||||
if (!installer_path) {
|
|
||||||
VLOG(1) << "Could not locate install.sh";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ShouldInstallDialog()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
base::mac::ScopedAuthorizationRef authorization(
|
|
||||||
MaybeShowAuthorizationDialog(application_directory));
|
|
||||||
// authorization will be NULL if it's deemed unnecessary or if
|
|
||||||
// authentication fails. In either case, try to install without privilege
|
|
||||||
// escalation.
|
|
||||||
|
|
||||||
if (!InstallFromDiskImage(authorization.release(),
|
|
||||||
installer_path,
|
|
||||||
source_path,
|
|
||||||
target_path)) {
|
|
||||||
ShowErrorDialog();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dock::AddIcon(target_path, source_path);
|
|
||||||
|
|
||||||
if (dmg_bsd_device_name.empty()) {
|
|
||||||
// Not fatal, just diagnostic.
|
|
||||||
LOG(ERROR) << "Could not determine disk image BSD device name";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!LaunchInstalledApp(target_path, dmg_bsd_device_name)) {
|
|
||||||
ShowErrorDialog();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@@ -18,7 +18,6 @@
|
|||||||
#include "base/mac/bundle_locations.h"
|
#include "base/mac/bundle_locations.h"
|
||||||
#include "base/mac/foundation_util.h"
|
#include "base/mac/foundation_util.h"
|
||||||
#include "base/mac/mac_logging.h"
|
#include "base/mac/mac_logging.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/memory/ref_counted.h"
|
#include "base/memory/ref_counted.h"
|
||||||
#include "base/strings/string_number_conversions.h"
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
@@ -111,8 +110,9 @@ class PerformBridge : public base::RefCountedThreadSafe<PerformBridge> {
|
|||||||
|
|
||||||
// Happens on a WorkerPool thread.
|
// Happens on a WorkerPool thread.
|
||||||
void Run() {
|
void Run() {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
[target_ performSelector:sel_ withObject:arg_];
|
[target_ performSelector:sel_ withObject:arg_];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base::scoped_nsobject<id> target_;
|
base::scoped_nsobject<id> target_;
|
||||||
|
@@ -23,7 +23,6 @@
|
|||||||
#include "base/files/scoped_file.h"
|
#include "base/files/scoped_file.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/mac/mac_logging.h"
|
#include "base/mac/mac_logging.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
#include "base/posix/eintr_wrapper.h"
|
#include "base/posix/eintr_wrapper.h"
|
||||||
@@ -266,137 +265,137 @@ void RelauncherSynchronizeWithParent() {
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
int RelauncherMain(const content::MainFunctionParams& main_parameters) {
|
int RelauncherMain(const content::MainFunctionParams& main_parameters) {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
// CommandLine rearranges the order of the arguments returned by
|
||||||
|
// main_parameters.argv(), rendering it impossible to determine which
|
||||||
|
// arguments originally came before kRelauncherArgSeparator and which came
|
||||||
|
// after. It's crucial to distinguish between these because only those
|
||||||
|
// after the separator should be given to the relaunched process; it's also
|
||||||
|
// important to not treat the path to the relaunched process as a "loose"
|
||||||
|
// argument. NXArgc and NXArgv are pointers to the original argc and argv as
|
||||||
|
// passed to main(), so use those. Access them through _NSGetArgc and
|
||||||
|
// _NSGetArgv because NXArgc and NXArgv are normally only available to a
|
||||||
|
// main executable via crt1.o and this code will run from a dylib, and
|
||||||
|
// because of http://crbug.com/139902.
|
||||||
|
const int* argcp = _NSGetArgc();
|
||||||
|
if (!argcp) {
|
||||||
|
NOTREACHED();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int argc = *argcp;
|
||||||
|
|
||||||
// CommandLine rearranges the order of the arguments returned by
|
const char* const* const* argvp = _NSGetArgv();
|
||||||
// main_parameters.argv(), rendering it impossible to determine which
|
if (!argvp) {
|
||||||
// arguments originally came before kRelauncherArgSeparator and which came
|
NOTREACHED();
|
||||||
// after. It's crucial to distinguish between these because only those
|
return 1;
|
||||||
// after the separator should be given to the relaunched process; it's also
|
}
|
||||||
// important to not treat the path to the relaunched process as a "loose"
|
const char* const* argv = *argvp;
|
||||||
// argument. NXArgc and NXArgv are pointers to the original argc and argv as
|
|
||||||
// passed to main(), so use those. Access them through _NSGetArgc and
|
|
||||||
// _NSGetArgv because NXArgc and NXArgv are normally only available to a
|
|
||||||
// main executable via crt1.o and this code will run from a dylib, and
|
|
||||||
// because of http://crbug.com/139902.
|
|
||||||
const int* argcp = _NSGetArgc();
|
|
||||||
if (!argcp) {
|
|
||||||
NOTREACHED();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
int argc = *argcp;
|
|
||||||
|
|
||||||
const char* const* const* argvp = _NSGetArgv();
|
if (argc < 4 || RelauncherTypeArg() != argv[1]) {
|
||||||
if (!argvp) {
|
LOG(ERROR) << "relauncher process invoked with unexpected arguments";
|
||||||
NOTREACHED();
|
return 1;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
const char* const* argv = *argvp;
|
|
||||||
|
|
||||||
if (argc < 4 || RelauncherTypeArg() != argv[1]) {
|
|
||||||
LOG(ERROR) << "relauncher process invoked with unexpected arguments";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
RelauncherSynchronizeWithParent();
|
|
||||||
|
|
||||||
// The capacity for relaunch_args is 4 less than argc, because it
|
|
||||||
// won't contain the argv[0] of the relauncher process, the
|
|
||||||
// RelauncherTypeArg() at argv[1], kRelauncherArgSeparator, or the
|
|
||||||
// executable path of the process to be launched.
|
|
||||||
base::scoped_nsobject<NSMutableArray> relaunch_args(
|
|
||||||
[[NSMutableArray alloc] initWithCapacity:argc - 4]);
|
|
||||||
|
|
||||||
// Figure out what to execute, what arguments to pass it, and whether to
|
|
||||||
// start it in the background.
|
|
||||||
bool background = false;
|
|
||||||
bool wait_for_staged_update = false;
|
|
||||||
bool in_relaunch_args = false;
|
|
||||||
std::string dmg_bsd_device_name;
|
|
||||||
bool seen_relaunch_executable = false;
|
|
||||||
std::string relaunch_executable;
|
|
||||||
const std::string relauncher_dmg_device_arg =
|
|
||||||
base::StringPrintf("--%s=", switches::kRelauncherProcessDMGDevice);
|
|
||||||
for (int argv_index = 2; argv_index < argc; ++argv_index) {
|
|
||||||
const std::string arg(argv[argv_index]);
|
|
||||||
|
|
||||||
// Strip any -psn_ arguments, as they apply to a specific process.
|
|
||||||
if (arg.compare(0, strlen(kPSNArg), kPSNArg) == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_relaunch_args) {
|
RelauncherSynchronizeWithParent();
|
||||||
if (arg == kRelauncherArgSeparator) {
|
|
||||||
in_relaunch_args = true;
|
|
||||||
} else if (arg == kRelauncherBackgroundArg) {
|
|
||||||
background = true;
|
|
||||||
} else if (arg == kRelauncherWaitForUpdateArg) {
|
|
||||||
wait_for_staged_update = true;
|
|
||||||
} else if (arg.compare(0, relauncher_dmg_device_arg.size(),
|
|
||||||
relauncher_dmg_device_arg) == 0) {
|
|
||||||
dmg_bsd_device_name.assign(
|
|
||||||
arg.substr(relauncher_dmg_device_arg.size()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!seen_relaunch_executable) {
|
|
||||||
// The first argument after kRelauncherBackgroundArg is the path to
|
|
||||||
// the executable file or .app bundle directory. The Launch Services
|
|
||||||
// interface wants this separate from the rest of the arguments. In
|
|
||||||
// the relaunched process, this path will still be visible at argv[0].
|
|
||||||
relaunch_executable.assign(arg);
|
|
||||||
seen_relaunch_executable = true;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
NSString* arg_string = base::SysUTF8ToNSString(arg);
|
// The capacity for relaunch_args is 4 less than argc, because it
|
||||||
if (!arg_string) {
|
// won't contain the argv[0] of the relauncher process, the
|
||||||
LOG(ERROR) << "base::SysUTF8ToNSString failed for " << arg;
|
// RelauncherTypeArg() at argv[1], kRelauncherArgSeparator, or the
|
||||||
return 1;
|
// executable path of the process to be launched.
|
||||||
|
base::scoped_nsobject<NSMutableArray> relaunch_args(
|
||||||
|
[[NSMutableArray alloc] initWithCapacity:argc - 4]);
|
||||||
|
|
||||||
|
// Figure out what to execute, what arguments to pass it, and whether to
|
||||||
|
// start it in the background.
|
||||||
|
bool background = false;
|
||||||
|
bool wait_for_staged_update = false;
|
||||||
|
bool in_relaunch_args = false;
|
||||||
|
std::string dmg_bsd_device_name;
|
||||||
|
bool seen_relaunch_executable = false;
|
||||||
|
std::string relaunch_executable;
|
||||||
|
const std::string relauncher_dmg_device_arg =
|
||||||
|
base::StringPrintf("--%s=", switches::kRelauncherProcessDMGDevice);
|
||||||
|
for (int argv_index = 2; argv_index < argc; ++argv_index) {
|
||||||
|
const std::string arg(argv[argv_index]);
|
||||||
|
|
||||||
|
// Strip any -psn_ arguments, as they apply to a specific process.
|
||||||
|
if (arg.compare(0, strlen(kPSNArg), kPSNArg) == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_relaunch_args) {
|
||||||
|
if (arg == kRelauncherArgSeparator) {
|
||||||
|
in_relaunch_args = true;
|
||||||
|
} else if (arg == kRelauncherBackgroundArg) {
|
||||||
|
background = true;
|
||||||
|
} else if (arg == kRelauncherWaitForUpdateArg) {
|
||||||
|
wait_for_staged_update = true;
|
||||||
|
} else if (arg.compare(0, relauncher_dmg_device_arg.size(),
|
||||||
|
relauncher_dmg_device_arg) == 0) {
|
||||||
|
dmg_bsd_device_name.assign(
|
||||||
|
arg.substr(relauncher_dmg_device_arg.size()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!seen_relaunch_executable) {
|
||||||
|
// The first argument after kRelauncherBackgroundArg is the path to
|
||||||
|
// the executable file or .app bundle directory. The Launch Services
|
||||||
|
// interface wants this separate from the rest of the arguments. In
|
||||||
|
// the relaunched process, this path will still be visible at argv[0].
|
||||||
|
relaunch_executable.assign(arg);
|
||||||
|
seen_relaunch_executable = true;
|
||||||
|
} else {
|
||||||
|
NSString* arg_string = base::SysUTF8ToNSString(arg);
|
||||||
|
if (!arg_string) {
|
||||||
|
LOG(ERROR) << "base::SysUTF8ToNSString failed for " << arg;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
[relaunch_args addObject:arg_string];
|
||||||
}
|
}
|
||||||
[relaunch_args addObject:arg_string];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!seen_relaunch_executable) {
|
||||||
|
LOG(ERROR) << "nothing to relaunch";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If an update is staged but not yet installed, wait for it to be
|
||||||
|
// installed.
|
||||||
|
if (wait_for_staged_update) {
|
||||||
|
base::scoped_nsobject<CrStagingKeyWatcher> watcher(
|
||||||
|
[[CrStagingKeyWatcher alloc] initWithPollingTime:0.5]);
|
||||||
|
[watcher waitForStagingKeyToClear];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString* path = base::SysUTF8ToNSString(relaunch_executable);
|
||||||
|
base::scoped_nsobject<NSURL> url([[NSURL alloc] initFileURLWithPath:path]);
|
||||||
|
NSDictionary* configuration =
|
||||||
|
@{NSWorkspaceLaunchConfigurationArguments : (relaunch_args.get())};
|
||||||
|
|
||||||
|
NSRunningApplication* application = [[NSWorkspace sharedWorkspace]
|
||||||
|
launchApplicationAtURL:url
|
||||||
|
options:NSWorkspaceLaunchDefault |
|
||||||
|
NSWorkspaceLaunchWithErrorPresentation |
|
||||||
|
(background ? NSWorkspaceLaunchWithoutActivation
|
||||||
|
: 0) |
|
||||||
|
NSWorkspaceLaunchNewInstance
|
||||||
|
configuration:configuration
|
||||||
|
error:nil];
|
||||||
|
if (!application) {
|
||||||
|
LOG(ERROR) << "Failed to relaunch " << relaunch_executable;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The application should have relaunched (or is in the process of
|
||||||
|
// relaunching). From this point on, only clean-up tasks should occur, and
|
||||||
|
// failures are tolerable.
|
||||||
|
|
||||||
|
if (!dmg_bsd_device_name.empty()) {
|
||||||
|
EjectAndTrashDiskImage(dmg_bsd_device_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!seen_relaunch_executable) {
|
|
||||||
LOG(ERROR) << "nothing to relaunch";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If an update is staged but not yet installed, wait for it to be installed.
|
|
||||||
if (wait_for_staged_update) {
|
|
||||||
base::scoped_nsobject<CrStagingKeyWatcher> watcher(
|
|
||||||
[[CrStagingKeyWatcher alloc] initWithPollingTime:0.5]);
|
|
||||||
[watcher waitForStagingKeyToClear];
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString* path = base::SysUTF8ToNSString(relaunch_executable);
|
|
||||||
base::scoped_nsobject<NSURL> url([[NSURL alloc] initFileURLWithPath:path]);
|
|
||||||
NSDictionary* configuration =
|
|
||||||
@{NSWorkspaceLaunchConfigurationArguments : (relaunch_args.get())};
|
|
||||||
|
|
||||||
NSRunningApplication *application = [[NSWorkspace sharedWorkspace]
|
|
||||||
launchApplicationAtURL:url
|
|
||||||
options:NSWorkspaceLaunchDefault |
|
|
||||||
NSWorkspaceLaunchWithErrorPresentation |
|
|
||||||
(background ? NSWorkspaceLaunchWithoutActivation
|
|
||||||
: 0) |
|
|
||||||
NSWorkspaceLaunchNewInstance
|
|
||||||
configuration:configuration
|
|
||||||
error:nil];
|
|
||||||
if (!application) {
|
|
||||||
LOG(ERROR) << "Failed to relaunch " << relaunch_executable;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The application should have relaunched (or is in the process of
|
|
||||||
// relaunching). From this point on, only clean-up tasks should occur, and
|
|
||||||
// failures are tolerable.
|
|
||||||
|
|
||||||
if (!dmg_bsd_device_name.empty()) {
|
|
||||||
EjectAndTrashDiskImage(dmg_bsd_device_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
#include "base/base_paths.h"
|
#include "base/base_paths.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#import "base/mac/foundation_util.h"
|
#import "base/mac/foundation_util.h"
|
||||||
#import "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/memory/free_deleter.h"
|
#include "base/memory/free_deleter.h"
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
#include "build/build_config.h"
|
#include "build/build_config.h"
|
||||||
@@ -24,48 +23,50 @@ namespace {
|
|||||||
// implementation of chrome::OuterAppBundle(), which should be the only
|
// implementation of chrome::OuterAppBundle(), which should be the only
|
||||||
// caller.
|
// caller.
|
||||||
NSBundle* OuterAppBundleInternal() {
|
NSBundle* OuterAppBundleInternal() {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
if (!base::mac::AmIBundled()) {
|
||||||
|
// If unbundled (as in a test), there's no app bundle.
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
if (!base::mac::AmIBundled()) {
|
if (!base::mac::IsBackgroundOnlyProcess()) {
|
||||||
// If unbundled (as in a test), there's no app bundle.
|
// Shortcut: in the browser process, just return the main app bundle.
|
||||||
return nil;
|
return [[NSBundle mainBundle] retain];
|
||||||
|
}
|
||||||
|
|
||||||
|
// From C.app/Contents/Frameworks/C.framework/Versions/1.2.3.4, go up five
|
||||||
|
// steps to C.app.
|
||||||
|
base::FilePath framework_path = chrome::GetFrameworkBundlePath();
|
||||||
|
base::FilePath outer_app_dir =
|
||||||
|
framework_path.DirName().DirName().DirName().DirName().DirName();
|
||||||
|
const char* outer_app_dir_c = outer_app_dir.value().c_str();
|
||||||
|
NSString* outer_app_dir_ns =
|
||||||
|
[NSString stringWithUTF8String:outer_app_dir_c];
|
||||||
|
|
||||||
|
return [[NSBundle bundleWithPath:outer_app_dir_ns] retain];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!base::mac::IsBackgroundOnlyProcess()) {
|
|
||||||
// Shortcut: in the browser process, just return the main app bundle.
|
|
||||||
return [[NSBundle mainBundle] retain];
|
|
||||||
}
|
|
||||||
|
|
||||||
// From C.app/Contents/Frameworks/C.framework/Versions/1.2.3.4, go up five
|
|
||||||
// steps to C.app.
|
|
||||||
base::FilePath framework_path = chrome::GetFrameworkBundlePath();
|
|
||||||
base::FilePath outer_app_dir =
|
|
||||||
framework_path.DirName().DirName().DirName().DirName().DirName();
|
|
||||||
const char* outer_app_dir_c = outer_app_dir.value().c_str();
|
|
||||||
NSString* outer_app_dir_ns = [NSString stringWithUTF8String:outer_app_dir_c];
|
|
||||||
|
|
||||||
return [[NSBundle bundleWithPath:outer_app_dir_ns] retain];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* ProductDirNameForBundle(NSBundle* chrome_bundle) {
|
char* ProductDirNameForBundle(NSBundle* chrome_bundle) {
|
||||||
const char* product_dir_name = NULL;
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
const char* product_dir_name = NULL;
|
||||||
|
|
||||||
NSString* product_dir_name_ns =
|
NSString* product_dir_name_ns =
|
||||||
[chrome_bundle objectForInfoDictionaryKey:@"CrProductDirName"];
|
[chrome_bundle objectForInfoDictionaryKey:@"CrProductDirName"];
|
||||||
product_dir_name = [product_dir_name_ns fileSystemRepresentation];
|
product_dir_name = [product_dir_name_ns fileSystemRepresentation];
|
||||||
|
|
||||||
if (!product_dir_name) {
|
if (!product_dir_name) {
|
||||||
#if defined(GOOGLE_CHROME_BUILD)
|
#if defined(GOOGLE_CHROME_BUILD)
|
||||||
product_dir_name = "Google/Chrome";
|
product_dir_name = "Google/Chrome";
|
||||||
#else
|
#else
|
||||||
product_dir_name = "Chromium";
|
product_dir_name = "Chromium";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leaked, but the only caller initializes a static with this result, so it
|
// Leaked, but the only caller initializes a static with this result, so it
|
||||||
// only happens once, and that's OK.
|
// only happens once, and that's OK.
|
||||||
return strdup(product_dir_name);
|
return strdup(product_dir_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProductDirName returns the name of the directory inside
|
// ProductDirName returns the name of the directory inside
|
||||||
|
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include "base/mac/foundation_util.h"
|
#include "base/mac/foundation_util.h"
|
||||||
#include "base/mac/scoped_cftyperef.h"
|
#include "base/mac/scoped_cftyperef.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/process/launch.h"
|
#include "base/process/launch.h"
|
||||||
#include "base/strings/stringprintf.h"
|
#include "base/strings/stringprintf.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
@@ -100,63 +99,67 @@ bool Launchd::RestartJob(Domain domain,
|
|||||||
Type type,
|
Type type,
|
||||||
CFStringRef name,
|
CFStringRef name,
|
||||||
CFStringRef cf_session_type) {
|
CFStringRef cf_session_type) {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
NSURL* url = GetPlistURL(domain, type, name);
|
NSURL* url = GetPlistURL(domain, type, name);
|
||||||
NSString* ns_path = [url path];
|
NSString* ns_path = [url path];
|
||||||
ns_path = SanitizeShellArgument(ns_path);
|
ns_path = SanitizeShellArgument(ns_path);
|
||||||
const char* file_path = [ns_path fileSystemRepresentation];
|
const char* file_path = [ns_path fileSystemRepresentation];
|
||||||
|
|
||||||
NSString* ns_session_type =
|
NSString* ns_session_type =
|
||||||
SanitizeShellArgument(base::mac::CFToNSCast(cf_session_type));
|
SanitizeShellArgument(base::mac::CFToNSCast(cf_session_type));
|
||||||
if (!file_path || !ns_session_type) {
|
if (!file_path || !ns_session_type) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> argv;
|
||||||
|
argv.push_back("/bin/bash");
|
||||||
|
argv.push_back("--noprofile");
|
||||||
|
argv.push_back("-c");
|
||||||
|
std::string command =
|
||||||
|
base::StringPrintf("/bin/launchctl unload -S %s %s;"
|
||||||
|
"/bin/launchctl load -S %s %s;",
|
||||||
|
[ns_session_type UTF8String], file_path,
|
||||||
|
[ns_session_type UTF8String], file_path);
|
||||||
|
argv.push_back(command);
|
||||||
|
|
||||||
|
base::LaunchOptions options;
|
||||||
|
options.new_process_group = true;
|
||||||
|
return base::LaunchProcess(argv, options).IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> argv;
|
|
||||||
argv.push_back("/bin/bash");
|
|
||||||
argv.push_back("--noprofile");
|
|
||||||
argv.push_back("-c");
|
|
||||||
std::string command = base::StringPrintf(
|
|
||||||
"/bin/launchctl unload -S %s %s;"
|
|
||||||
"/bin/launchctl load -S %s %s;",
|
|
||||||
[ns_session_type UTF8String], file_path,
|
|
||||||
[ns_session_type UTF8String], file_path);
|
|
||||||
argv.push_back(command);
|
|
||||||
|
|
||||||
base::LaunchOptions options;
|
|
||||||
options.new_process_group = true;
|
|
||||||
return base::LaunchProcess(argv, options).IsValid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CFMutableDictionaryRef Launchd::CreatePlistFromFile(Domain domain,
|
CFMutableDictionaryRef Launchd::CreatePlistFromFile(Domain domain,
|
||||||
Type type,
|
Type type,
|
||||||
CFStringRef name) {
|
CFStringRef name) {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
NSURL* ns_url = GetPlistURL(domain, type, name);
|
NSURL* ns_url = GetPlistURL(domain, type, name);
|
||||||
NSMutableDictionary* plist =
|
NSMutableDictionary* plist =
|
||||||
[[NSMutableDictionary alloc] initWithContentsOfURL:ns_url];
|
[[NSMutableDictionary alloc] initWithContentsOfURL:ns_url];
|
||||||
return base::mac::NSToCFCast(plist);
|
return base::mac::NSToCFCast(plist);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Launchd::WritePlistToFile(Domain domain,
|
bool Launchd::WritePlistToFile(Domain domain,
|
||||||
Type type,
|
Type type,
|
||||||
CFStringRef name,
|
CFStringRef name,
|
||||||
CFDictionaryRef dict) {
|
CFDictionaryRef dict) {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
NSURL* ns_url = GetPlistURL(domain, type, name);
|
NSURL* ns_url = GetPlistURL(domain, type, name);
|
||||||
return [base::mac::CFToNSCast(dict) writeToURL:ns_url atomically:YES];
|
return [base::mac::CFToNSCast(dict) writeToURL:ns_url atomically:YES];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Launchd::DeletePlist(Domain domain, Type type, CFStringRef name) {
|
bool Launchd::DeletePlist(Domain domain, Type type, CFStringRef name) {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
NSURL* ns_url = GetPlistURL(domain, type, name);
|
NSURL* ns_url = GetPlistURL(domain, type, name);
|
||||||
NSError* err = nil;
|
NSError* err = nil;
|
||||||
if (![[NSFileManager defaultManager] removeItemAtPath:[ns_url path]
|
if (![[NSFileManager defaultManager] removeItemAtPath:[ns_url path]
|
||||||
error:&err]) {
|
error:&err]) {
|
||||||
if ([err code] != NSFileNoSuchFileError) {
|
if ([err code] != NSFileNoSuchFileError) {
|
||||||
DLOG(ERROR) << "DeletePlist: " << base::mac::NSToCFCast(err);
|
DLOG(ERROR) << "DeletePlist: " << base::mac::NSToCFCast(err);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,6 @@
|
|||||||
#include "base/mac/bundle_locations.h"
|
#include "base/mac/bundle_locations.h"
|
||||||
#include "base/mac/foundation_util.h"
|
#include "base/mac/foundation_util.h"
|
||||||
#include "base/mac/mac_util.h"
|
#include "base/mac/mac_util.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
#include "base/metrics/histogram_macros.h"
|
#include "base/metrics/histogram_macros.h"
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
@@ -37,10 +36,11 @@ namespace {
|
|||||||
#define kServiceProcessSessionType "Aqua"
|
#define kServiceProcessSessionType "Aqua"
|
||||||
|
|
||||||
CFStringRef CopyServiceProcessLaunchDName() {
|
CFStringRef CopyServiceProcessLaunchDName() {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
NSBundle* bundle = base::mac::FrameworkBundle();
|
NSBundle* bundle = base::mac::FrameworkBundle();
|
||||||
return CFStringCreateCopy(kCFAllocatorDefault,
|
return CFStringCreateCopy(kCFAllocatorDefault,
|
||||||
base::mac::NSToCFCast([bundle bundleIdentifier]));
|
base::mac::NSToCFCast([bundle bundleIdentifier]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString* GetServiceProcessLaunchDLabel() {
|
NSString* GetServiceProcessLaunchDLabel() {
|
||||||
@@ -105,44 +105,46 @@ bool ForceServiceProcessShutdown(const std::string& /* version */,
|
|||||||
|
|
||||||
bool ServiceProcessState::GetServiceProcessData(std::string* version,
|
bool ServiceProcessState::GetServiceProcessData(std::string* version,
|
||||||
base::ProcessId* pid) {
|
base::ProcessId* pid) {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
std::string label = base::SysNSStringToUTF8(GetServiceProcessLaunchDLabel());
|
std::string label =
|
||||||
mac::services::JobInfo info;
|
base::SysNSStringToUTF8(GetServiceProcessLaunchDLabel());
|
||||||
if (!Launchd::GetInstance()->GetJobInfo(label, &info))
|
mac::services::JobInfo info;
|
||||||
return false;
|
if (!Launchd::GetInstance()->GetJobInfo(label, &info))
|
||||||
// Anything past here will return true in that there does appear
|
return false;
|
||||||
// to be a service process of some sort registered with launchd.
|
// Anything past here will return true in that there does appear
|
||||||
if (version) {
|
// to be a service process of some sort registered with launchd.
|
||||||
*version = "0";
|
if (version) {
|
||||||
NSString* exe_path = base::SysUTF8ToNSString(info.program);
|
*version = "0";
|
||||||
if (exe_path) {
|
NSString* exe_path = base::SysUTF8ToNSString(info.program);
|
||||||
NSString* bundle_path = [[[exe_path stringByDeletingLastPathComponent]
|
if (exe_path) {
|
||||||
stringByDeletingLastPathComponent]
|
NSString* bundle_path = [[[exe_path stringByDeletingLastPathComponent]
|
||||||
stringByDeletingLastPathComponent];
|
stringByDeletingLastPathComponent]
|
||||||
NSBundle* bundle = [NSBundle bundleWithPath:bundle_path];
|
stringByDeletingLastPathComponent];
|
||||||
if (bundle) {
|
NSBundle* bundle = [NSBundle bundleWithPath:bundle_path];
|
||||||
NSString* ns_version =
|
if (bundle) {
|
||||||
[bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
|
NSString* ns_version =
|
||||||
if (ns_version) {
|
[bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
|
||||||
*version = base::SysNSStringToUTF8(ns_version);
|
if (ns_version) {
|
||||||
|
*version = base::SysNSStringToUTF8(ns_version);
|
||||||
|
} else {
|
||||||
|
DLOG(ERROR) << "Unable to get version at: "
|
||||||
|
<< reinterpret_cast<CFStringRef>(bundle_path);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
DLOG(ERROR) << "Unable to get version at: "
|
// The bundle has been deleted out from underneath the registered
|
||||||
|
// job.
|
||||||
|
DLOG(ERROR) << "Unable to get bundle at: "
|
||||||
<< reinterpret_cast<CFStringRef>(bundle_path);
|
<< reinterpret_cast<CFStringRef>(bundle_path);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// The bundle has been deleted out from underneath the registered
|
DLOG(ERROR) << "Unable to get executable path for service process";
|
||||||
// job.
|
|
||||||
DLOG(ERROR) << "Unable to get bundle at: "
|
|
||||||
<< reinterpret_cast<CFStringRef>(bundle_path);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
DLOG(ERROR) << "Unable to get executable path for service process";
|
|
||||||
}
|
}
|
||||||
|
if (pid) {
|
||||||
|
*pid = info.pid ? *info.pid : -1;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (pid) {
|
|
||||||
*pid = info.pid ? *info.pid : -1;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServiceProcessState::Initialize() {
|
bool ServiceProcessState::Initialize() {
|
||||||
@@ -211,43 +213,41 @@ mac::services::JobOptions GetServiceProcessJobOptions(
|
|||||||
|
|
||||||
CFDictionaryRef CreateServiceProcessLaunchdPlist(base::CommandLine* cmd_line,
|
CFDictionaryRef CreateServiceProcessLaunchdPlist(base::CommandLine* cmd_line,
|
||||||
bool for_auto_launch) {
|
bool for_auto_launch) {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
NSString* program = base::SysUTF8ToNSString(cmd_line->GetProgram().value());
|
||||||
|
|
||||||
NSString* program =
|
std::vector<std::string> args = cmd_line->argv();
|
||||||
base::SysUTF8ToNSString(cmd_line->GetProgram().value());
|
NSMutableArray* ns_args = [NSMutableArray arrayWithCapacity:args.size()];
|
||||||
|
|
||||||
std::vector<std::string> args = cmd_line->argv();
|
for (std::vector<std::string>::iterator iter = args.begin();
|
||||||
NSMutableArray* ns_args = [NSMutableArray arrayWithCapacity:args.size()];
|
iter < args.end(); ++iter) {
|
||||||
|
[ns_args addObject:base::SysUTF8ToNSString(*iter)];
|
||||||
|
}
|
||||||
|
|
||||||
for (std::vector<std::string>::iterator iter = args.begin();
|
// See the man page for launchd.plist.
|
||||||
iter < args.end();
|
NSMutableDictionary* launchd_plist = [@{
|
||||||
++iter) {
|
@LAUNCH_JOBKEY_LABEL : GetServiceProcessLaunchDLabel(),
|
||||||
[ns_args addObject:base::SysUTF8ToNSString(*iter)];
|
@LAUNCH_JOBKEY_PROGRAM : program,
|
||||||
|
@LAUNCH_JOBKEY_PROGRAMARGUMENTS : ns_args,
|
||||||
|
@LAUNCH_JOBKEY_MACHSERVICES : GetServiceProcessMachName(),
|
||||||
|
} mutableCopy];
|
||||||
|
|
||||||
|
if (for_auto_launch) {
|
||||||
|
// We want the service process to be able to exit if there are no services
|
||||||
|
// enabled. With a value of NO in the SuccessfulExit key, launchd will
|
||||||
|
// relaunch the service automatically in any other case than exiting
|
||||||
|
// cleanly with a 0 return code.
|
||||||
|
NSDictionary* keep_alive =
|
||||||
|
@{@LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT : @NO};
|
||||||
|
NSDictionary* auto_launchd_plist = @{
|
||||||
|
@LAUNCH_JOBKEY_RUNATLOAD : @YES,
|
||||||
|
@LAUNCH_JOBKEY_KEEPALIVE : keep_alive,
|
||||||
|
@LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE : @kServiceProcessSessionType
|
||||||
|
};
|
||||||
|
[launchd_plist addEntriesFromDictionary:auto_launchd_plist];
|
||||||
|
}
|
||||||
|
return reinterpret_cast<CFDictionaryRef>(launchd_plist);
|
||||||
}
|
}
|
||||||
|
|
||||||
// See the man page for launchd.plist.
|
|
||||||
NSMutableDictionary* launchd_plist = [@{
|
|
||||||
@LAUNCH_JOBKEY_LABEL : GetServiceProcessLaunchDLabel(),
|
|
||||||
@LAUNCH_JOBKEY_PROGRAM : program,
|
|
||||||
@LAUNCH_JOBKEY_PROGRAMARGUMENTS : ns_args,
|
|
||||||
@LAUNCH_JOBKEY_MACHSERVICES : GetServiceProcessMachName(),
|
|
||||||
} mutableCopy];
|
|
||||||
|
|
||||||
if (for_auto_launch) {
|
|
||||||
// We want the service process to be able to exit if there are no services
|
|
||||||
// enabled. With a value of NO in the SuccessfulExit key, launchd will
|
|
||||||
// relaunch the service automatically in any other case than exiting
|
|
||||||
// cleanly with a 0 return code.
|
|
||||||
NSDictionary* keep_alive =
|
|
||||||
@{ @LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT : @NO };
|
|
||||||
NSDictionary* auto_launchd_plist = @{
|
|
||||||
@LAUNCH_JOBKEY_RUNATLOAD : @YES,
|
|
||||||
@LAUNCH_JOBKEY_KEEPALIVE : keep_alive,
|
|
||||||
@LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE : @kServiceProcessSessionType
|
|
||||||
};
|
|
||||||
[launchd_plist addEntriesFromDictionary:auto_launchd_plist];
|
|
||||||
}
|
|
||||||
return reinterpret_cast<CFDictionaryRef>(launchd_plist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writes the launchd property list into the user's LaunchAgents directory,
|
// Writes the launchd property list into the user's LaunchAgents directory,
|
||||||
@@ -272,24 +272,23 @@ bool ServiceProcessState::RemoveFromAutoRun() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ServiceProcessState::StateData::WatchExecutable() {
|
bool ServiceProcessState::StateData::WatchExecutable() {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
base::FilePath executable_path = base::FilePath(job_info.program);
|
||||||
base::FilePath executable_path = base::FilePath(job_info.program);
|
std::unique_ptr<ExecFilePathWatcherCallback> callback(
|
||||||
std::unique_ptr<ExecFilePathWatcherCallback> callback(
|
new ExecFilePathWatcherCallback);
|
||||||
new ExecFilePathWatcherCallback);
|
if (!callback->Init(executable_path)) {
|
||||||
if (!callback->Init(executable_path)) {
|
DLOG(ERROR) << "executable_watcher.Init " << executable_path.value();
|
||||||
DLOG(ERROR) << "executable_watcher.Init " << executable_path.value();
|
return false;
|
||||||
return false;
|
}
|
||||||
|
if (!executable_watcher.Watch(
|
||||||
|
executable_path, false,
|
||||||
|
base::Bind(&ExecFilePathWatcherCallback::NotifyPathChanged,
|
||||||
|
base::Owned(callback.release())))) {
|
||||||
|
DLOG(ERROR) << "executable_watcher.watch " << executable_path.value();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (!executable_watcher.Watch(
|
|
||||||
executable_path,
|
|
||||||
false,
|
|
||||||
base::Bind(&ExecFilePathWatcherCallback::NotifyPathChanged,
|
|
||||||
base::Owned(callback.release())))) {
|
|
||||||
DLOG(ERROR) << "executable_watcher.watch " << executable_path.value();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExecFilePathWatcherCallback::Init(const base::FilePath& path) {
|
bool ExecFilePathWatcherCallback::Init(const base::FilePath& path) {
|
||||||
@@ -306,103 +305,100 @@ void ExecFilePathWatcherCallback::NotifyPathChanged(const base::FilePath& path,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
bool needs_shutdown = false;
|
bool needs_shutdown = false;
|
||||||
bool needs_restart = false;
|
bool needs_restart = false;
|
||||||
bool good_bundle = false;
|
bool good_bundle = false;
|
||||||
|
|
||||||
// Go from bundle/Contents/MacOS/executable to bundle.
|
// Go from bundle/Contents/MacOS/executable to bundle.
|
||||||
NSURL* bundle_url = [[[executable_fsref_ URLByDeletingLastPathComponent]
|
NSURL* bundle_url = [[[executable_fsref_ URLByDeletingLastPathComponent]
|
||||||
URLByDeletingLastPathComponent] URLByDeletingLastPathComponent];
|
URLByDeletingLastPathComponent] URLByDeletingLastPathComponent];
|
||||||
if (bundle_url) {
|
if (bundle_url) {
|
||||||
base::ScopedCFTypeRef<CFBundleRef> bundle(
|
base::ScopedCFTypeRef<CFBundleRef> bundle(CFBundleCreate(
|
||||||
CFBundleCreate(kCFAllocatorDefault, base::mac::NSToCFCast(bundle_url)));
|
kCFAllocatorDefault, base::mac::NSToCFCast(bundle_url)));
|
||||||
good_bundle = CFBundleGetIdentifier(bundle) != NULL;
|
good_bundle = CFBundleGetIdentifier(bundle) != NULL;
|
||||||
}
|
|
||||||
|
|
||||||
if (!good_bundle) {
|
|
||||||
needs_shutdown = true;
|
|
||||||
} else {
|
|
||||||
bool in_trash = false;
|
|
||||||
NSFileManager* file_manager = [NSFileManager defaultManager];
|
|
||||||
NSURLRelationship relationship;
|
|
||||||
if ([file_manager getRelationship:&relationship
|
|
||||||
ofDirectory:NSTrashDirectory
|
|
||||||
inDomain:0
|
|
||||||
toItemAtURL:executable_fsref_
|
|
||||||
error:nil]) {
|
|
||||||
in_trash = relationship == NSURLRelationshipContains;
|
|
||||||
}
|
}
|
||||||
if (in_trash) {
|
|
||||||
|
if (!good_bundle) {
|
||||||
needs_shutdown = true;
|
needs_shutdown = true;
|
||||||
} else {
|
} else {
|
||||||
bool was_moved = true;
|
bool in_trash = false;
|
||||||
NSString* path_string = base::mac::FilePathToNSString(path);
|
NSFileManager* file_manager = [NSFileManager defaultManager];
|
||||||
NSURL* path_url = [NSURL fileURLWithPath:path_string isDirectory:NO];
|
NSURLRelationship relationship;
|
||||||
NSURL* path_ref = [path_url fileReferenceURL];
|
if ([file_manager getRelationship:&relationship
|
||||||
if (path_ref != nil) {
|
ofDirectory:NSTrashDirectory
|
||||||
if ([path_ref isEqual:executable_fsref_]) {
|
inDomain:0
|
||||||
was_moved = false;
|
toItemAtURL:executable_fsref_
|
||||||
|
error:nil]) {
|
||||||
|
in_trash = relationship == NSURLRelationshipContains;
|
||||||
|
}
|
||||||
|
if (in_trash) {
|
||||||
|
needs_shutdown = true;
|
||||||
|
} else {
|
||||||
|
bool was_moved = true;
|
||||||
|
NSString* path_string = base::mac::FilePathToNSString(path);
|
||||||
|
NSURL* path_url = [NSURL fileURLWithPath:path_string isDirectory:NO];
|
||||||
|
NSURL* path_ref = [path_url fileReferenceURL];
|
||||||
|
if (path_ref != nil) {
|
||||||
|
if ([path_ref isEqual:executable_fsref_]) {
|
||||||
|
was_moved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (was_moved) {
|
||||||
|
needs_restart = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (was_moved) {
|
|
||||||
needs_restart = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
if (needs_shutdown || needs_restart) {
|
||||||
if (needs_shutdown || needs_restart) {
|
// First deal with the plist.
|
||||||
// First deal with the plist.
|
base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName());
|
||||||
base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName());
|
if (needs_restart) {
|
||||||
if (needs_restart) {
|
base::ScopedCFTypeRef<CFMutableDictionaryRef> plist(
|
||||||
base::ScopedCFTypeRef<CFMutableDictionaryRef> plist(
|
Launchd::GetInstance()->CreatePlistFromFile(Launchd::User,
|
||||||
Launchd::GetInstance()->CreatePlistFromFile(
|
Launchd::Agent, name));
|
||||||
Launchd::User, Launchd::Agent, name));
|
if (plist.get()) {
|
||||||
if (plist.get()) {
|
NSMutableDictionary* ns_plist = base::mac::CFToNSCast(plist);
|
||||||
NSMutableDictionary* ns_plist = base::mac::CFToNSCast(plist);
|
NSURL* new_path = [executable_fsref_ filePathURL];
|
||||||
NSURL* new_path = [executable_fsref_ filePathURL];
|
DCHECK([new_path isFileURL]);
|
||||||
DCHECK([new_path isFileURL]);
|
NSString* ns_new_path = [new_path path];
|
||||||
NSString* ns_new_path = [new_path path];
|
ns_plist[@LAUNCH_JOBKEY_PROGRAM] = ns_new_path;
|
||||||
ns_plist[@LAUNCH_JOBKEY_PROGRAM] = ns_new_path;
|
base::scoped_nsobject<NSMutableArray> args(
|
||||||
base::scoped_nsobject<NSMutableArray> args(
|
[ns_plist[@LAUNCH_JOBKEY_PROGRAMARGUMENTS] mutableCopy]);
|
||||||
[ns_plist[@LAUNCH_JOBKEY_PROGRAMARGUMENTS] mutableCopy]);
|
args[0] = ns_new_path;
|
||||||
args[0] = ns_new_path;
|
ns_plist[@LAUNCH_JOBKEY_PROGRAMARGUMENTS] = args;
|
||||||
ns_plist[@LAUNCH_JOBKEY_PROGRAMARGUMENTS] = args;
|
if (!Launchd::GetInstance()->WritePlistToFile(
|
||||||
if (!Launchd::GetInstance()->WritePlistToFile(Launchd::User,
|
Launchd::User, Launchd::Agent, name, plist)) {
|
||||||
Launchd::Agent,
|
DLOG(ERROR) << "Unable to rewrite plist.";
|
||||||
name,
|
needs_shutdown = true;
|
||||||
plist)) {
|
}
|
||||||
DLOG(ERROR) << "Unable to rewrite plist.";
|
} else {
|
||||||
|
DLOG(ERROR) << "Unable to read plist.";
|
||||||
needs_shutdown = true;
|
needs_shutdown = true;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
DLOG(ERROR) << "Unable to read plist.";
|
|
||||||
needs_shutdown = true;
|
|
||||||
}
|
}
|
||||||
}
|
if (needs_shutdown) {
|
||||||
if (needs_shutdown) {
|
if (!RemoveFromLaunchd()) {
|
||||||
if (!RemoveFromLaunchd()) {
|
DLOG(ERROR) << "Unable to RemoveFromLaunchd.";
|
||||||
DLOG(ERROR) << "Unable to RemoveFromLaunchd.";
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Then deal with the process.
|
// Then deal with the process.
|
||||||
CFStringRef session_type = CFSTR(kServiceProcessSessionType);
|
CFStringRef session_type = CFSTR(kServiceProcessSessionType);
|
||||||
if (needs_restart) {
|
if (needs_restart) {
|
||||||
if (!Launchd::GetInstance()->RestartJob(Launchd::User,
|
if (!Launchd::GetInstance()->RestartJob(Launchd::User, Launchd::Agent,
|
||||||
Launchd::Agent,
|
name, session_type)) {
|
||||||
name,
|
DLOG(ERROR) << "RestartLaunchdJob";
|
||||||
session_type)) {
|
needs_shutdown = true;
|
||||||
DLOG(ERROR) << "RestartLaunchdJob";
|
}
|
||||||
needs_shutdown = true;
|
|
||||||
}
|
}
|
||||||
}
|
if (needs_shutdown) {
|
||||||
if (needs_shutdown) {
|
const std::string& label =
|
||||||
const std::string& label =
|
base::SysNSStringToUTF8(GetServiceProcessLaunchDLabel());
|
||||||
base::SysNSStringToUTF8(GetServiceProcessLaunchDLabel());
|
if (!Launchd::GetInstance()->RemoveJob(label)) {
|
||||||
if (!Launchd::GetInstance()->RemoveJob(label)) {
|
DLOG(ERROR) << "RemoveJob " << label;
|
||||||
DLOG(ERROR) << "RemoveJob " << label;
|
// Exiting with zero, so launchd doesn't restart the process.
|
||||||
// Exiting with zero, so launchd doesn't restart the process.
|
exit(0);
|
||||||
exit(0);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include "chrome/test/base/in_process_browser_test.h"
|
#include "chrome/test/base/in_process_browser_test.h"
|
||||||
|
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "chrome/browser/devtools/devtools_window.h"
|
#include "chrome/browser/devtools/devtools_window.h"
|
||||||
#include "chrome/browser/profiles/profile.h"
|
#include "chrome/browser/profiles/profile.h"
|
||||||
#include "chrome/browser/ui/browser.h"
|
#include "chrome/browser/ui/browser.h"
|
||||||
@@ -18,26 +17,26 @@ void InProcessBrowserTest::OpenDevToolsWindow(
|
|||||||
content::WebContents* web_contents) {
|
content::WebContents* web_contents) {
|
||||||
// Opening a Devtools Window can cause AppKit to throw objects into the
|
// Opening a Devtools Window can cause AppKit to throw objects into the
|
||||||
// autorelease pool. Flush the pool when this function returns.
|
// autorelease pool. Flush the pool when this function returns.
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
ASSERT_FALSE(content::DevToolsAgentHost::HasFor(web_contents));
|
||||||
ASSERT_FALSE(content::DevToolsAgentHost::HasFor(web_contents));
|
DevToolsWindow::OpenDevToolsWindow(web_contents);
|
||||||
DevToolsWindow::OpenDevToolsWindow(web_contents);
|
ASSERT_TRUE(content::DevToolsAgentHost::HasFor(web_contents));
|
||||||
ASSERT_TRUE(content::DevToolsAgentHost::HasFor(web_contents));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Browser* InProcessBrowserTest::OpenURLOffTheRecord(Profile* profile,
|
Browser* InProcessBrowserTest::OpenURLOffTheRecord(Profile* profile,
|
||||||
const GURL& url) {
|
const GURL& url) {
|
||||||
// Opening an incognito window can cause AppKit to throw objects into the
|
// Opening an incognito window can cause AppKit to throw objects into the
|
||||||
// autorelease pool. Flush the pool when this function returns.
|
// autorelease pool. Flush the pool when this function returns.
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
chrome::OpenURLOffTheRecord(profile, url);
|
||||||
chrome::OpenURLOffTheRecord(profile, url);
|
Browser* browser =
|
||||||
Browser* browser =
|
chrome::FindTabbedBrowser(profile->GetOffTheRecordProfile(), false);
|
||||||
chrome::FindTabbedBrowser(profile->GetOffTheRecordProfile(), false);
|
content::TestNavigationObserver observer(
|
||||||
content::TestNavigationObserver observer(
|
browser->tab_strip_model()->GetActiveWebContents());
|
||||||
browser->tab_strip_model()->GetActiveWebContents());
|
observer.Wait();
|
||||||
observer.Wait();
|
return browser;
|
||||||
return browser;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a browser with a single tab (about:blank), waits for the tab to
|
// Creates a browser with a single tab (about:blank), waits for the tab to
|
||||||
@@ -45,48 +44,48 @@ Browser* InProcessBrowserTest::OpenURLOffTheRecord(Profile* profile,
|
|||||||
Browser* InProcessBrowserTest::CreateBrowser(Profile* profile) {
|
Browser* InProcessBrowserTest::CreateBrowser(Profile* profile) {
|
||||||
// Making a browser window can cause AppKit to throw objects into the
|
// Making a browser window can cause AppKit to throw objects into the
|
||||||
// autorelease pool. Flush the pool when this function returns.
|
// autorelease pool. Flush the pool when this function returns.
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
Browser* browser = new Browser(Browser::CreateParams(profile, true));
|
||||||
Browser* browser = new Browser(Browser::CreateParams(profile, true));
|
AddBlankTabAndShow(browser);
|
||||||
AddBlankTabAndShow(browser);
|
return browser;
|
||||||
return browser;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Browser* InProcessBrowserTest::CreateIncognitoBrowser(Profile* profile) {
|
Browser* InProcessBrowserTest::CreateIncognitoBrowser(Profile* profile) {
|
||||||
// Making a browser window can cause AppKit to throw objects into the
|
// Making a browser window can cause AppKit to throw objects into the
|
||||||
// autorelease pool. Flush the pool when this function returns.
|
// autorelease pool. Flush the pool when this function returns.
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
// Use active profile if default nullptr was passed.
|
||||||
|
if (!profile)
|
||||||
|
profile = browser()->profile();
|
||||||
|
|
||||||
// Use active profile if default nullptr was passed.
|
// Create a new browser with using the incognito profile.
|
||||||
if (!profile)
|
Browser* incognito = new Browser(
|
||||||
profile = browser()->profile();
|
Browser::CreateParams(profile->GetOffTheRecordProfile(), true));
|
||||||
|
AddBlankTabAndShow(incognito);
|
||||||
// Create a new browser with using the incognito profile.
|
return incognito;
|
||||||
Browser* incognito = new Browser(
|
}
|
||||||
Browser::CreateParams(profile->GetOffTheRecordProfile(), true));
|
|
||||||
AddBlankTabAndShow(incognito);
|
|
||||||
return incognito;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Browser* InProcessBrowserTest::CreateBrowserForPopup(Profile* profile) {
|
Browser* InProcessBrowserTest::CreateBrowserForPopup(Profile* profile) {
|
||||||
// Making a browser window can cause AppKit to throw objects into the
|
// Making a browser window can cause AppKit to throw objects into the
|
||||||
// autorelease pool. Flush the pool when this function returns.
|
// autorelease pool. Flush the pool when this function returns.
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
Browser* browser =
|
||||||
Browser* browser =
|
new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile, true));
|
||||||
new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile, true));
|
AddBlankTabAndShow(browser);
|
||||||
AddBlankTabAndShow(browser);
|
return browser;
|
||||||
return browser;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Browser* InProcessBrowserTest::CreateBrowserForApp(const std::string& app_name,
|
Browser* InProcessBrowserTest::CreateBrowserForApp(const std::string& app_name,
|
||||||
Profile* profile) {
|
Profile* profile) {
|
||||||
// Making a browser window can cause AppKit to throw objects into the
|
// Making a browser window can cause AppKit to throw objects into the
|
||||||
// autorelease pool. Flush the pool when this function returns.
|
// autorelease pool. Flush the pool when this function returns.
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
Browser* browser = new Browser(Browser::CreateParams::CreateForApp(
|
||||||
Browser* browser = new Browser(Browser::CreateParams::CreateForApp(
|
app_name, false /* trusted_source */, gfx::Rect(), profile, true));
|
||||||
app_name, false /* trusted_source */, gfx::Rect(), profile, true));
|
AddBlankTabAndShow(browser);
|
||||||
AddBlankTabAndShow(browser);
|
return browser;
|
||||||
return browser;
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
#include "base/files/file_util.h"
|
#include "base/files/file_util.h"
|
||||||
#include "base/i18n/icu_util.h"
|
#include "base/i18n/icu_util.h"
|
||||||
#include "base/i18n/message_formatter.h"
|
#include "base/i18n/message_formatter.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
#include "base/strings/string_piece.h"
|
#include "base/strings/string_piece.h"
|
||||||
#include "base/strings/string_util.h"
|
#include "base/strings/string_util.h"
|
||||||
@@ -154,188 +153,188 @@ const char kAppType_Helper[] = "helper"; // Helper app
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int main(int argc, char* const argv[]) {
|
int main(int argc, char* const argv[]) {
|
||||||
base::mac::ScopedNSAutoreleasePool autorelease_pool;
|
@autoreleasepool {
|
||||||
|
const char* version_file_path = NULL;
|
||||||
|
const char* grit_output_dir = NULL;
|
||||||
|
const char* branding_strings_name = NULL;
|
||||||
|
const char* output_dir = NULL;
|
||||||
|
const char* app_type = kAppType_Main;
|
||||||
|
|
||||||
const char* version_file_path = NULL;
|
// Process the args
|
||||||
const char* grit_output_dir = NULL;
|
int ch;
|
||||||
const char* branding_strings_name = NULL;
|
while ((ch = getopt(argc, argv, "t:v:g:b:o:")) != -1) {
|
||||||
const char* output_dir = NULL;
|
switch (ch) {
|
||||||
const char* app_type = kAppType_Main;
|
case 't':
|
||||||
|
app_type = optarg;
|
||||||
// Process the args
|
break;
|
||||||
int ch;
|
case 'v':
|
||||||
while ((ch = getopt(argc, argv, "t:v:g:b:o:")) != -1) {
|
version_file_path = optarg;
|
||||||
switch (ch) {
|
break;
|
||||||
case 't':
|
case 'g':
|
||||||
app_type = optarg;
|
grit_output_dir = optarg;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'b':
|
||||||
version_file_path = optarg;
|
branding_strings_name = optarg;
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'o':
|
||||||
grit_output_dir = optarg;
|
output_dir = optarg;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
default:
|
||||||
branding_strings_name = optarg;
|
fprintf(stderr, "ERROR: bad command line arg\n");
|
||||||
break;
|
exit(1);
|
||||||
case 'o':
|
break;
|
||||||
output_dir = optarg;
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "ERROR: bad command line arg\n");
|
|
||||||
exit(1);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
argc -= optind;
|
||||||
argc -= optind;
|
argv += optind;
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
#define CHECK_ARG(a, b) \
|
#define CHECK_ARG(a, b) \
|
||||||
do { \
|
do { \
|
||||||
if ((a)) { \
|
if ((a)) { \
|
||||||
fprintf(stderr, "ERROR: " b "\n"); \
|
fprintf(stderr, "ERROR: " b "\n"); \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
} \
|
} \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
// Check our args
|
// Check our args
|
||||||
CHECK_ARG(!version_file_path, "Missing VERSION file path");
|
CHECK_ARG(!version_file_path, "Missing VERSION file path");
|
||||||
CHECK_ARG(!grit_output_dir, "Missing grit output dir path");
|
CHECK_ARG(!grit_output_dir, "Missing grit output dir path");
|
||||||
CHECK_ARG(!output_dir, "Missing path to write InfoPlist.strings files");
|
CHECK_ARG(!output_dir, "Missing path to write InfoPlist.strings files");
|
||||||
CHECK_ARG(!branding_strings_name, "Missing branding strings file name");
|
CHECK_ARG(!branding_strings_name, "Missing branding strings file name");
|
||||||
CHECK_ARG(argc == 0, "Missing language list");
|
CHECK_ARG(argc == 0, "Missing language list");
|
||||||
CHECK_ARG((strcmp(app_type, kAppType_Main) != 0 &&
|
CHECK_ARG((strcmp(app_type, kAppType_Main) != 0 &&
|
||||||
strcmp(app_type, kAppType_Helper) != 0),
|
strcmp(app_type, kAppType_Helper) != 0),
|
||||||
"Unknown app type");
|
"Unknown app type");
|
||||||
|
|
||||||
char* const* lang_list = argv;
|
char* const* lang_list = argv;
|
||||||
int lang_list_count = argc;
|
int lang_list_count = argc;
|
||||||
|
|
||||||
base::i18n::InitializeICU();
|
base::i18n::InitializeICU();
|
||||||
|
|
||||||
// Parse the version file and build our string
|
// Parse the version file and build our string
|
||||||
NSString* version_string = ApplicationVersionString(version_file_path);
|
NSString* version_string = ApplicationVersionString(version_file_path);
|
||||||
if (!version_string) {
|
if (!version_string) {
|
||||||
fprintf(stderr, "ERROR: failed to get a version string");
|
fprintf(stderr, "ERROR: failed to get a version string");
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
NSFileManager* fm = [NSFileManager defaultManager];
|
|
||||||
|
|
||||||
for (int loop = 0; loop < lang_list_count; ++loop) {
|
|
||||||
const char* cur_lang = lang_list[loop];
|
|
||||||
|
|
||||||
// Open the branded string pak file
|
|
||||||
std::unique_ptr<ui::DataPack> branded_data_pack(
|
|
||||||
LoadResourceDataPack(grit_output_dir, branding_strings_name, cur_lang));
|
|
||||||
if (branded_data_pack.get() == NULL) {
|
|
||||||
fprintf(stderr, "ERROR: Failed to load branded pak for language: %s\n",
|
|
||||||
cur_lang);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t name_id = IDS_PRODUCT_NAME;
|
NSFileManager* fm = [NSFileManager defaultManager];
|
||||||
const char* name_id_str = "IDS_PRODUCT_NAME";
|
|
||||||
uint32_t short_name_id = IDS_APP_MENU_PRODUCT_NAME;
|
|
||||||
const char* short_name_id_str = "IDS_APP_MENU_PRODUCT_NAME";
|
|
||||||
if (strcmp(app_type, kAppType_Helper) == 0) {
|
|
||||||
name_id = IDS_HELPER_NAME;
|
|
||||||
name_id_str = "IDS_HELPER_NAME";
|
|
||||||
short_name_id = IDS_SHORT_HELPER_NAME;
|
|
||||||
short_name_id_str = "IDS_SHORT_HELPER_NAME";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch the strings.
|
for (int loop = 0; loop < lang_list_count; ++loop) {
|
||||||
NSString* name =
|
const char* cur_lang = lang_list[loop];
|
||||||
|
|
||||||
|
// Open the branded string pak file
|
||||||
|
std::unique_ptr<ui::DataPack> branded_data_pack(
|
||||||
|
LoadResourceDataPack(grit_output_dir, branding_strings_name, cur_lang));
|
||||||
|
if (branded_data_pack.get() == NULL) {
|
||||||
|
fprintf(stderr, "ERROR: Failed to load branded pak for language: %s\n",
|
||||||
|
cur_lang);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t name_id = IDS_PRODUCT_NAME;
|
||||||
|
const char* name_id_str = "IDS_PRODUCT_NAME";
|
||||||
|
uint32_t short_name_id = IDS_APP_MENU_PRODUCT_NAME;
|
||||||
|
const char* short_name_id_str = "IDS_APP_MENU_PRODUCT_NAME";
|
||||||
|
if (strcmp(app_type, kAppType_Helper) == 0) {
|
||||||
|
name_id = IDS_HELPER_NAME;
|
||||||
|
name_id_str = "IDS_HELPER_NAME";
|
||||||
|
short_name_id = IDS_SHORT_HELPER_NAME;
|
||||||
|
short_name_id_str = "IDS_SHORT_HELPER_NAME";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the strings.
|
||||||
|
NSString* name =
|
||||||
|
LoadStringFromDataPack(branded_data_pack.get(), cur_lang,
|
||||||
|
name_id, name_id_str);
|
||||||
|
NSString* short_name =
|
||||||
|
LoadStringFromDataPack(branded_data_pack.get(), cur_lang,
|
||||||
|
short_name_id, short_name_id_str);
|
||||||
|
NSString* copyright_format =
|
||||||
LoadStringFromDataPack(branded_data_pack.get(), cur_lang,
|
LoadStringFromDataPack(branded_data_pack.get(), cur_lang,
|
||||||
name_id, name_id_str);
|
IDS_ABOUT_VERSION_COPYRIGHT,
|
||||||
NSString* short_name =
|
"IDS_ABOUT_VERSION_COPYRIGHT");
|
||||||
|
|
||||||
|
NSString* copyright = base::SysUTF16ToNSString(
|
||||||
|
base::i18n::MessageFormatter::FormatWithNumberedArgs(
|
||||||
|
base::SysNSStringToUTF16(copyright_format), base::Time::Now()));
|
||||||
|
|
||||||
|
NSString* permission_reason =
|
||||||
LoadStringFromDataPack(branded_data_pack.get(), cur_lang,
|
LoadStringFromDataPack(branded_data_pack.get(), cur_lang,
|
||||||
short_name_id, short_name_id_str);
|
IDS_RUNTIME_PERMISSION_OS_REASON_TEXT,
|
||||||
NSString* copyright_format =
|
"IDS_RUNTIME_PERMISSION_OS_REASON_TEXT");
|
||||||
LoadStringFromDataPack(branded_data_pack.get(), cur_lang,
|
|
||||||
IDS_ABOUT_VERSION_COPYRIGHT,
|
|
||||||
"IDS_ABOUT_VERSION_COPYRIGHT");
|
|
||||||
|
|
||||||
NSString* copyright = base::SysUTF16ToNSString(
|
// For now, assume this is ok for all languages. If we need to, this could
|
||||||
base::i18n::MessageFormatter::FormatWithNumberedArgs(
|
// be moved into generated_resources.grd and fetched.
|
||||||
base::SysNSStringToUTF16(copyright_format), base::Time::Now()));
|
NSString* get_info = [NSString
|
||||||
|
stringWithFormat:@"%@ %@, %@", name, version_string, copyright];
|
||||||
|
|
||||||
NSString* permission_reason =
|
// Generate the InfoPlist.strings file contents.
|
||||||
LoadStringFromDataPack(branded_data_pack.get(), cur_lang,
|
NSDictionary<NSString*, NSString*>* infoplist_strings = @{
|
||||||
IDS_RUNTIME_PERMISSION_OS_REASON_TEXT,
|
@"CFBundleDisplayName" : name,
|
||||||
"IDS_RUNTIME_PERMISSION_OS_REASON_TEXT");
|
@"CFBundleGetInfoString" : get_info,
|
||||||
|
@"CFBundleName" : short_name,
|
||||||
|
@"NSHumanReadableCopyright" : copyright,
|
||||||
|
@"NSLocationUsageDescription" : permission_reason,
|
||||||
|
@"NSMicrophoneUsageDescription" : permission_reason,
|
||||||
|
@"NSCameraUsageDescription" : permission_reason,
|
||||||
|
@"NSBluetoothPeripheralUsageDescription" : permission_reason,
|
||||||
|
};
|
||||||
|
base::scoped_nsobject<NSMutableString> strings_file_contents_string(
|
||||||
|
[[NSMutableString alloc] init]);
|
||||||
|
for (NSString* key in infoplist_strings) {
|
||||||
|
[strings_file_contents_string
|
||||||
|
appendFormat:@"%@ = \"%@\";\n", key,
|
||||||
|
EscapeForStringsFileValue(infoplist_strings[key])];
|
||||||
|
}
|
||||||
|
|
||||||
// For now, assume this is ok for all languages. If we need to, this could
|
// We set up Xcode projects expecting strings files to be UTF8, so make
|
||||||
// be moved into generated_resources.grd and fetched.
|
// sure we write the data in that form. When Xcode copies them it will
|
||||||
NSString* get_info = [NSString
|
// put them final runtime encoding.
|
||||||
stringWithFormat:@"%@ %@, %@", name, version_string, copyright];
|
NSData* strings_file_contents_utf8 =
|
||||||
|
[strings_file_contents_string dataUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
|
||||||
// Generate the InfoPlist.strings file contents.
|
if ([strings_file_contents_utf8 length] == 0) {
|
||||||
NSDictionary<NSString*, NSString*>* infoplist_strings = @{
|
fprintf(stderr, "ERROR: failed to get the utf8 encoding of the strings "
|
||||||
@"CFBundleDisplayName" : name,
|
"file for language: %s\n", cur_lang);
|
||||||
@"CFBundleGetInfoString" : get_info,
|
exit(1);
|
||||||
@"CFBundleName" : short_name,
|
}
|
||||||
@"NSHumanReadableCopyright" : copyright,
|
|
||||||
@"NSLocationUsageDescription" : permission_reason,
|
// For Cocoa to find the locale at runtime, it needs to use '_' instead of
|
||||||
@"NSMicrophoneUsageDescription" : permission_reason,
|
// '-' (http://crbug.com/20441). Also, 'en-US' should be represented
|
||||||
@"NSCameraUsageDescription" : permission_reason,
|
// simply as 'en' (http://crbug.com/19165, http://crbug.com/25578).
|
||||||
@"NSBluetoothPeripheralUsageDescription" : permission_reason,
|
NSString* cur_lang_ns = [NSString stringWithUTF8String:cur_lang];
|
||||||
};
|
if ([cur_lang_ns isEqualToString:@"en-US"]) {
|
||||||
base::scoped_nsobject<NSMutableString> strings_file_contents_string(
|
cur_lang_ns = @"en";
|
||||||
[[NSMutableString alloc] init]);
|
}
|
||||||
for (NSString* key in infoplist_strings) {
|
cur_lang_ns = [cur_lang_ns stringByReplacingOccurrencesOfString:@"-"
|
||||||
[strings_file_contents_string
|
withString:@"_"];
|
||||||
appendFormat:@"%@ = \"%@\";\n", key,
|
// Make sure the lproj we write to exists
|
||||||
EscapeForStringsFileValue(infoplist_strings[key])];
|
NSString *lproj_name = [NSString stringWithFormat:@"%@.lproj", cur_lang_ns];
|
||||||
}
|
NSString *output_path =
|
||||||
|
[[NSString stringWithUTF8String:output_dir]
|
||||||
// We set up Xcode projects expecting strings files to be UTF8, so make
|
stringByAppendingPathComponent:lproj_name];
|
||||||
// sure we write the data in that form. When Xcode copies them it will
|
NSError* error = nil;
|
||||||
// put them final runtime encoding.
|
if (![fm fileExistsAtPath:output_path] &&
|
||||||
NSData* strings_file_contents_utf8 =
|
![fm createDirectoryAtPath:output_path
|
||||||
[strings_file_contents_string dataUsingEncoding:NSUTF8StringEncoding];
|
withIntermediateDirectories:YES
|
||||||
|
attributes:nil
|
||||||
if ([strings_file_contents_utf8 length] == 0) {
|
error:&error]) {
|
||||||
fprintf(stderr, "ERROR: failed to get the utf8 encoding of the strings "
|
fprintf(stderr, "ERROR: '%s' didn't exist or we failed to create it\n",
|
||||||
"file for language: %s\n", cur_lang);
|
[output_path UTF8String]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For Cocoa to find the locale at runtime, it needs to use '_' instead of
|
// Write out the file
|
||||||
// '-' (http://crbug.com/20441). Also, 'en-US' should be represented
|
output_path =
|
||||||
// simply as 'en' (http://crbug.com/19165, http://crbug.com/25578).
|
[output_path stringByAppendingPathComponent:@"InfoPlist.strings"];
|
||||||
NSString* cur_lang_ns = [NSString stringWithUTF8String:cur_lang];
|
if (![strings_file_contents_utf8 writeToFile:output_path
|
||||||
if ([cur_lang_ns isEqualToString:@"en-US"]) {
|
atomically:YES]) {
|
||||||
cur_lang_ns = @"en";
|
fprintf(stderr, "ERROR: Failed to write out '%s'\n",
|
||||||
}
|
[output_path UTF8String]);
|
||||||
cur_lang_ns = [cur_lang_ns stringByReplacingOccurrencesOfString:@"-"
|
exit(1);
|
||||||
withString:@"_"];
|
}
|
||||||
// Make sure the lproj we write to exists
|
|
||||||
NSString *lproj_name = [NSString stringWithFormat:@"%@.lproj", cur_lang_ns];
|
|
||||||
NSString *output_path =
|
|
||||||
[[NSString stringWithUTF8String:output_dir]
|
|
||||||
stringByAppendingPathComponent:lproj_name];
|
|
||||||
NSError* error = nil;
|
|
||||||
if (![fm fileExistsAtPath:output_path] &&
|
|
||||||
![fm createDirectoryAtPath:output_path
|
|
||||||
withIntermediateDirectories:YES
|
|
||||||
attributes:nil
|
|
||||||
error:&error]) {
|
|
||||||
fprintf(stderr, "ERROR: '%s' didn't exist or we failed to create it\n",
|
|
||||||
[output_path UTF8String]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write out the file
|
|
||||||
output_path =
|
|
||||||
[output_path stringByAppendingPathComponent:@"InfoPlist.strings"];
|
|
||||||
if (![strings_file_contents_utf8 writeToFile:output_path
|
|
||||||
atomically:YES]) {
|
|
||||||
fprintf(stderr, "ERROR: Failed to write out '%s'\n",
|
|
||||||
[output_path UTF8String]);
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@@ -7,24 +7,24 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
#import "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "components/history/core/test/thumbnail-inl.h"
|
#include "components/history/core/test/thumbnail-inl.h"
|
||||||
#include "ui/gfx/image/image.h"
|
#include "ui/gfx/image/image.h"
|
||||||
|
|
||||||
namespace history {
|
namespace history {
|
||||||
|
|
||||||
gfx::Image CreateGoogleThumbnailForTest() {
|
gfx::Image CreateGoogleThumbnailForTest() {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
// -[NSData dataWithBytesNoCopy:length:freeWhenDone:] takes it first parameter
|
// -[NSData dataWithBytesNoCopy:length:freeWhenDone:] takes its first
|
||||||
// as a void* but does not modify it (API is not const clean) so we need to
|
// parameter as a void* but does not modify it (API is not const clean) so
|
||||||
// use const_cast<> here.
|
// we need to use const_cast<> here.
|
||||||
NSData* data =
|
NSData* data = [NSData
|
||||||
[NSData dataWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(
|
dataWithBytesNoCopy:const_cast<void*>(
|
||||||
kGoogleThumbnail))
|
static_cast<const void*>(kGoogleThumbnail))
|
||||||
length:sizeof(kGoogleThumbnail)
|
length:sizeof(kGoogleThumbnail)
|
||||||
freeWhenDone:NO];
|
freeWhenDone:NO];
|
||||||
UIImage* image = [UIImage imageWithData:data scale:1];
|
UIImage* image = [UIImage imageWithData:data scale:1];
|
||||||
return gfx::Image([image retain]);
|
return gfx::Image([image retain]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -8,7 +8,6 @@
|
|||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/files/file_util.h"
|
#include "base/files/file_util.h"
|
||||||
#include "base/mac/foundation_util.h"
|
#include "base/mac/foundation_util.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
#include "base/version.h"
|
#include "base/version.h"
|
||||||
@@ -45,29 +44,28 @@ base::Time GetUpdaterSettingsTime(NSString* value_name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
base::Version GetVersionFromPlist(const base::FilePath& info_plist) {
|
base::Version GetVersionFromPlist(const base::FilePath& info_plist) {
|
||||||
base::mac::ScopedNSAutoreleasePool scoped_pool;
|
@autoreleasepool {
|
||||||
NSData* data =
|
NSData* data = [NSData
|
||||||
[NSData dataWithContentsOfFile:
|
dataWithContentsOfFile:base::mac::FilePathToNSString(info_plist)];
|
||||||
base::mac::FilePathToNSString(info_plist)];
|
if ([data length] == 0) {
|
||||||
if ([data length] == 0) {
|
return base::Version();
|
||||||
return base::Version();
|
}
|
||||||
|
NSDictionary* all_keys =
|
||||||
|
base::mac::ObjCCastStrict<NSDictionary>([NSPropertyListSerialization
|
||||||
|
propertyListWithData:data
|
||||||
|
options:NSPropertyListImmutable
|
||||||
|
format:nil
|
||||||
|
error:nil]);
|
||||||
|
if (all_keys == nil) {
|
||||||
|
return base::Version();
|
||||||
|
}
|
||||||
|
CFStringRef version = base::mac::GetValueFromDictionary<CFStringRef>(
|
||||||
|
base::mac::NSToCFCast(all_keys), kCFBundleVersionKey);
|
||||||
|
if (version == NULL) {
|
||||||
|
return base::Version();
|
||||||
|
}
|
||||||
|
return base::Version(base::SysCFStringRefToUTF8(version));
|
||||||
}
|
}
|
||||||
NSDictionary* all_keys = base::mac::ObjCCastStrict<NSDictionary>(
|
|
||||||
[NSPropertyListSerialization propertyListWithData:data
|
|
||||||
options:NSPropertyListImmutable
|
|
||||||
format:nil
|
|
||||||
error:nil]);
|
|
||||||
if (all_keys == nil) {
|
|
||||||
return base::Version();
|
|
||||||
}
|
|
||||||
CFStringRef version =
|
|
||||||
base::mac::GetValueFromDictionary<CFStringRef>(
|
|
||||||
base::mac::NSToCFCast(all_keys),
|
|
||||||
kCFBundleVersionKey);
|
|
||||||
if (version == NULL) {
|
|
||||||
return base::Version();
|
|
||||||
}
|
|
||||||
return base::Version(base::SysCFStringRefToUTF8(version));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include "content/browser/renderer_host/input/synthetic_gesture_target_mac.h"
|
#include "content/browser/renderer_host/input/synthetic_gesture_target_mac.h"
|
||||||
|
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||||
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
|
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
|
||||||
#import "content/app_shim_remote_cocoa/render_widget_host_view_cocoa.h"
|
#import "content/app_shim_remote_cocoa/render_widget_host_view_cocoa.h"
|
||||||
@@ -88,42 +87,42 @@ void SyntheticGestureTargetMac::DispatchWebGestureEventToPlatform(
|
|||||||
const ui::LatencyInfo& latency_info) {
|
const ui::LatencyInfo& latency_info) {
|
||||||
// Create an autorelease pool so that we clean up any synthetic events we
|
// Create an autorelease pool so that we clean up any synthetic events we
|
||||||
// generate.
|
// generate.
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
NSPoint content_local = NSMakePoint(
|
||||||
|
web_gesture.PositionInWidget().x,
|
||||||
|
[cocoa_view_ frame].size.height - web_gesture.PositionInWidget().y);
|
||||||
|
NSPoint location_in_window = [cocoa_view_ convertPoint:content_local
|
||||||
|
toView:nil];
|
||||||
|
|
||||||
NSPoint content_local = NSMakePoint(
|
switch (web_gesture.GetType()) {
|
||||||
web_gesture.PositionInWidget().x,
|
case WebInputEvent::kGesturePinchBegin: {
|
||||||
[cocoa_view_ frame].size.height - web_gesture.PositionInWidget().y);
|
id cocoa_event =
|
||||||
NSPoint location_in_window =
|
[SyntheticPinchEvent eventWithMagnification:0.0f
|
||||||
[cocoa_view_ convertPoint:content_local toView:nil];
|
locationInWindow:location_in_window
|
||||||
|
phase:NSEventPhaseBegan];
|
||||||
switch (web_gesture.GetType()) {
|
[cocoa_view_ handleBeginGestureWithEvent:cocoa_event
|
||||||
case WebInputEvent::kGesturePinchBegin: {
|
isSyntheticallyInjected:YES];
|
||||||
id cocoa_event =
|
return;
|
||||||
[SyntheticPinchEvent eventWithMagnification:0.0f
|
}
|
||||||
locationInWindow:location_in_window
|
case WebInputEvent::kGesturePinchEnd: {
|
||||||
phase:NSEventPhaseBegan];
|
id cocoa_event =
|
||||||
[cocoa_view_ handleBeginGestureWithEvent:cocoa_event
|
[SyntheticPinchEvent eventWithMagnification:0.0f
|
||||||
isSyntheticallyInjected:YES];
|
locationInWindow:location_in_window
|
||||||
return;
|
phase:NSEventPhaseEnded];
|
||||||
|
[cocoa_view_ handleEndGestureWithEvent:cocoa_event];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case WebInputEvent::kGesturePinchUpdate: {
|
||||||
|
id cocoa_event = [SyntheticPinchEvent
|
||||||
|
eventWithMagnification:web_gesture.data.pinch_update.scale - 1.0f
|
||||||
|
locationInWindow:location_in_window
|
||||||
|
phase:NSEventPhaseChanged];
|
||||||
|
[cocoa_view_ magnifyWithEvent:cocoa_event];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
NOTREACHED();
|
||||||
}
|
}
|
||||||
case WebInputEvent::kGesturePinchEnd: {
|
|
||||||
id cocoa_event =
|
|
||||||
[SyntheticPinchEvent eventWithMagnification:0.0f
|
|
||||||
locationInWindow:location_in_window
|
|
||||||
phase:NSEventPhaseEnded];
|
|
||||||
[cocoa_view_ handleEndGestureWithEvent:cocoa_event];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case WebInputEvent::kGesturePinchUpdate: {
|
|
||||||
id cocoa_event = [SyntheticPinchEvent
|
|
||||||
eventWithMagnification:web_gesture.data.pinch_update.scale - 1.0f
|
|
||||||
locationInWindow:location_in_window
|
|
||||||
phase:NSEventPhaseChanged];
|
|
||||||
[cocoa_view_ magnifyWithEvent:cocoa_event];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/stl_util.h"
|
#include "base/stl_util.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
#include "ppapi/c/dev/ppb_truetype_font_dev.h"
|
#include "ppapi/c/dev/ppb_truetype_font_dev.h"
|
||||||
@@ -36,47 +35,49 @@ const NSInteger kPepperFontWeightsLength = base::size(kPepperFontWeights);
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void GetFontFamilies_SlowBlocking(std::vector<std::string>* font_families) {
|
void GetFontFamilies_SlowBlocking(std::vector<std::string>* font_families) {
|
||||||
base::mac::ScopedNSAutoreleasePool autorelease_pool;
|
@autoreleasepool {
|
||||||
NSFontManager* fontManager = [[[NSFontManager alloc] init] autorelease];
|
NSFontManager* fontManager = [[[NSFontManager alloc] init] autorelease];
|
||||||
NSArray* fonts = [fontManager availableFontFamilies];
|
NSArray* fonts = [fontManager availableFontFamilies];
|
||||||
font_families->reserve([fonts count]);
|
font_families->reserve([fonts count]);
|
||||||
for (NSString* family_name in fonts)
|
for (NSString* family_name in fonts)
|
||||||
font_families->push_back(base::SysNSStringToUTF8(family_name));
|
font_families->push_back(base::SysNSStringToUTF8(family_name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetFontsInFamily_SlowBlocking(
|
void GetFontsInFamily_SlowBlocking(
|
||||||
const std::string& family,
|
const std::string& family,
|
||||||
std::vector<ppapi::proxy::SerializedTrueTypeFontDesc>* fonts_in_family) {
|
std::vector<ppapi::proxy::SerializedTrueTypeFontDesc>* fonts_in_family) {
|
||||||
base::mac::ScopedNSAutoreleasePool autorelease_pool;
|
@autoreleasepool {
|
||||||
NSFontManager* fontManager = [[[NSFontManager alloc] init] autorelease];
|
NSFontManager* fontManager = [[[NSFontManager alloc] init] autorelease];
|
||||||
NSString* ns_family = base::SysUTF8ToNSString(family);
|
NSString* ns_family = base::SysUTF8ToNSString(family);
|
||||||
NSArray* ns_fonts_in_family =
|
NSArray* ns_fonts_in_family =
|
||||||
[fontManager availableMembersOfFontFamily:ns_family];
|
[fontManager availableMembersOfFontFamily:ns_family];
|
||||||
|
|
||||||
for (NSArray* font_info in ns_fonts_in_family) {
|
for (NSArray* font_info in ns_fonts_in_family) {
|
||||||
ppapi::proxy::SerializedTrueTypeFontDesc desc;
|
ppapi::proxy::SerializedTrueTypeFontDesc desc;
|
||||||
desc.family = family;
|
desc.family = family;
|
||||||
NSInteger font_weight = [[font_info objectAtIndex:2] intValue];
|
NSInteger font_weight = [[font_info objectAtIndex:2] intValue];
|
||||||
font_weight = std::max(static_cast<NSInteger>(0), font_weight);
|
font_weight = std::max(static_cast<NSInteger>(0), font_weight);
|
||||||
font_weight = std::min(kPepperFontWeightsLength - 1, font_weight);
|
font_weight = std::min(kPepperFontWeightsLength - 1, font_weight);
|
||||||
desc.weight = kPepperFontWeights[font_weight];
|
desc.weight = kPepperFontWeights[font_weight];
|
||||||
|
|
||||||
NSFontTraitMask font_traits =
|
NSFontTraitMask font_traits =
|
||||||
[[font_info objectAtIndex:3] unsignedIntValue];
|
[[font_info objectAtIndex:3] unsignedIntValue];
|
||||||
desc.style = PP_TRUETYPEFONTSTYLE_NORMAL;
|
desc.style = PP_TRUETYPEFONTSTYLE_NORMAL;
|
||||||
if (font_traits & NSItalicFontMask)
|
if (font_traits & NSItalicFontMask)
|
||||||
desc.style = PP_TRUETYPEFONTSTYLE_ITALIC;
|
desc.style = PP_TRUETYPEFONTSTYLE_ITALIC;
|
||||||
|
|
||||||
desc.width = PP_TRUETYPEFONTWIDTH_NORMAL;
|
desc.width = PP_TRUETYPEFONTWIDTH_NORMAL;
|
||||||
if (font_traits & NSCondensedFontMask)
|
if (font_traits & NSCondensedFontMask)
|
||||||
desc.width = PP_TRUETYPEFONTWIDTH_CONDENSED;
|
desc.width = PP_TRUETYPEFONTWIDTH_CONDENSED;
|
||||||
else if (font_traits & NSExpandedFontMask)
|
else if (font_traits & NSExpandedFontMask)
|
||||||
desc.width = PP_TRUETYPEFONTWIDTH_EXPANDED;
|
desc.width = PP_TRUETYPEFONTWIDTH_EXPANDED;
|
||||||
|
|
||||||
// Mac doesn't support requesting non-default character sets.
|
// Mac doesn't support requesting non-default character sets.
|
||||||
desc.charset = PP_TRUETYPEFONTCHARSET_DEFAULT;
|
desc.charset = PP_TRUETYPEFONTCHARSET_DEFAULT;
|
||||||
|
|
||||||
fonts_in_family->push_back(desc);
|
fonts_in_family->push_back(desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -140,45 +140,45 @@ TEST_F(RenderWidgetHostViewMacEditCommandHelperWithTaskEnvTest,
|
|||||||
supported_factors.push_back(ui::SCALE_FACTOR_100P);
|
supported_factors.push_back(ui::SCALE_FACTOR_100P);
|
||||||
ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);
|
ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);
|
||||||
|
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
int32_t routing_id = process_host->GetNextRoutingID();
|
||||||
|
mojom::WidgetPtr widget;
|
||||||
|
std::unique_ptr<MockWidgetImpl> widget_impl =
|
||||||
|
std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
|
||||||
|
|
||||||
int32_t routing_id = process_host->GetNextRoutingID();
|
RenderWidgetHostImpl* render_widget = new RenderWidgetHostImpl(
|
||||||
mojom::WidgetPtr widget;
|
&delegate, process_host, routing_id, std::move(widget), false);
|
||||||
std::unique_ptr<MockWidgetImpl> widget_impl =
|
|
||||||
std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
|
|
||||||
|
|
||||||
RenderWidgetHostImpl* render_widget = new RenderWidgetHostImpl(
|
ui::WindowResizeHelperMac::Get()->Init(base::ThreadTaskRunnerHandle::Get());
|
||||||
&delegate, process_host, routing_id, std::move(widget), false);
|
|
||||||
|
|
||||||
ui::WindowResizeHelperMac::Get()->Init(base::ThreadTaskRunnerHandle::Get());
|
// Owned by its |GetInProcessNSView()|, i.e. |rwhv_cocoa|.
|
||||||
|
RenderWidgetHostViewMac* rwhv_mac =
|
||||||
|
new RenderWidgetHostViewMac(render_widget, false);
|
||||||
|
base::scoped_nsobject<RenderWidgetHostViewCocoa> rwhv_cocoa(
|
||||||
|
[rwhv_mac->GetInProcessNSView() retain]);
|
||||||
|
|
||||||
// Owned by its |GetInProcessNSView()|, i.e. |rwhv_cocoa|.
|
RenderWidgetHostViewMacEditCommandHelper helper;
|
||||||
RenderWidgetHostViewMac* rwhv_mac = new RenderWidgetHostViewMac(
|
NSArray* edit_command_strings = helper.GetEditSelectorNames();
|
||||||
render_widget, false);
|
RenderWidgetHostNSViewHostOwner* rwhwvm_owner =
|
||||||
base::scoped_nsobject<RenderWidgetHostViewCocoa> rwhv_cocoa(
|
[[[RenderWidgetHostNSViewHostOwner alloc]
|
||||||
[rwhv_mac->GetInProcessNSView() retain]);
|
initWithRenderWidgetHostViewMac:rwhv_mac] autorelease];
|
||||||
|
|
||||||
RenderWidgetHostViewMacEditCommandHelper helper;
|
helper.AddEditingSelectorsToClass([rwhwvm_owner class]);
|
||||||
NSArray* edit_command_strings = helper.GetEditSelectorNames();
|
|
||||||
RenderWidgetHostNSViewHostOwner* rwhwvm_owner =
|
|
||||||
[[[RenderWidgetHostNSViewHostOwner alloc]
|
|
||||||
initWithRenderWidgetHostViewMac:rwhv_mac] autorelease];
|
|
||||||
|
|
||||||
helper.AddEditingSelectorsToClass([rwhwvm_owner class]);
|
for (NSString* edit_command_name in edit_command_strings) {
|
||||||
|
NSString* sel_str = [edit_command_name stringByAppendingString:@":"];
|
||||||
|
[rwhwvm_owner performSelector:NSSelectorFromString(sel_str)
|
||||||
|
withObject:nil];
|
||||||
|
}
|
||||||
|
|
||||||
for (NSString* edit_command_name in edit_command_strings) {
|
size_t num_edit_commands = [edit_command_strings count];
|
||||||
NSString* sel_str = [edit_command_name stringByAppendingString:@":"];
|
EXPECT_EQ(delegate.edit_command_message_count_, num_edit_commands);
|
||||||
[rwhwvm_owner performSelector:NSSelectorFromString(sel_str) withObject:nil];
|
rwhv_cocoa.reset();
|
||||||
|
|
||||||
|
// The |render_widget|'s process needs to be deleted within |message_loop|.
|
||||||
|
delete render_widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t num_edit_commands = [edit_command_strings count];
|
|
||||||
EXPECT_EQ(delegate.edit_command_message_count_, num_edit_commands);
|
|
||||||
rwhv_cocoa.reset();
|
|
||||||
pool.Recycle();
|
|
||||||
|
|
||||||
// The |render_widget|'s process needs to be deleted within |message_loop|.
|
|
||||||
delete render_widget;
|
|
||||||
|
|
||||||
ui::WindowResizeHelperMac::Get()->ShutdownForTests();
|
ui::WindowResizeHelperMac::Get()->ShutdownForTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,38 +8,38 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
|
|
||||||
namespace content {
|
namespace content {
|
||||||
|
|
||||||
std::unique_ptr<base::ListValue> GetFontList_SlowBlocking() {
|
std::unique_ptr<base::ListValue> GetFontList_SlowBlocking() {
|
||||||
base::mac::ScopedNSAutoreleasePool autorelease_pool;
|
@autoreleasepool {
|
||||||
std::unique_ptr<base::ListValue> font_list(new base::ListValue);
|
std::unique_ptr<base::ListValue> font_list(new base::ListValue);
|
||||||
NSFontManager* fontManager = [[[NSFontManager alloc] init] autorelease];
|
NSFontManager* fontManager = [[[NSFontManager alloc] init] autorelease];
|
||||||
NSMutableDictionary* fonts_dict = [NSMutableDictionary dictionary];
|
NSMutableDictionary* fonts_dict = [NSMutableDictionary dictionary];
|
||||||
NSArray* fonts = [fontManager availableFontFamilies];
|
NSArray* fonts = [fontManager availableFontFamilies];
|
||||||
|
|
||||||
for (NSString* family_name in fonts) {
|
for (NSString* family_name in fonts) {
|
||||||
NSString* localized_family_name =
|
NSString* localized_family_name =
|
||||||
[fontManager localizedNameForFamily:family_name face:nil];
|
[fontManager localizedNameForFamily:family_name face:nil];
|
||||||
fonts_dict[family_name] = localized_family_name;
|
fonts_dict[family_name] = localized_family_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort family names based on localized names.
|
||||||
|
NSArray* sortedFonts = [fonts_dict
|
||||||
|
keysSortedByValueUsingSelector:@selector(localizedStandardCompare:)];
|
||||||
|
|
||||||
|
for (NSString* family_name in sortedFonts) {
|
||||||
|
NSString* localized_family_name = fonts_dict[family_name];
|
||||||
|
auto font_item = std::make_unique<base::ListValue>();
|
||||||
|
font_item->AppendString(base::SysNSStringToUTF16(family_name));
|
||||||
|
font_item->AppendString(base::SysNSStringToUTF16(localized_family_name));
|
||||||
|
font_list->Append(std::move(font_item));
|
||||||
|
}
|
||||||
|
|
||||||
|
return font_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort family names based on localized names.
|
|
||||||
NSArray* sortedFonts = [fonts_dict
|
|
||||||
keysSortedByValueUsingSelector:@selector(localizedStandardCompare:)];
|
|
||||||
|
|
||||||
for (NSString* family_name in sortedFonts) {
|
|
||||||
NSString* localized_family_name = fonts_dict[family_name];
|
|
||||||
auto font_item = std::make_unique<base::ListValue>();
|
|
||||||
font_item->AppendString(base::SysNSStringToUTF16(family_name));
|
|
||||||
font_item->AppendString(base::SysNSStringToUTF16(localized_family_name));
|
|
||||||
font_list->Append(std::move(font_item));
|
|
||||||
}
|
|
||||||
|
|
||||||
return font_list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace content
|
} // namespace content
|
||||||
|
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/mac/scoped_cftyperef.h"
|
#include "base/mac/scoped_cftyperef.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/memory/ptr_util.h"
|
#include "base/memory/ptr_util.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
@@ -87,57 +86,57 @@ void PrintingContextMac::AskUserForSettings(int max_pages,
|
|||||||
PrintSettingsCallback callback) {
|
PrintSettingsCallback callback) {
|
||||||
// Exceptions can also happen when the NSPrintPanel is being
|
// Exceptions can also happen when the NSPrintPanel is being
|
||||||
// deallocated, so it must be autoreleased within this scope.
|
// deallocated, so it must be autoreleased within this scope.
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
DCHECK([NSThread isMainThread]);
|
||||||
|
|
||||||
DCHECK([NSThread isMainThread]);
|
// We deliberately don't feed max_pages into the dialog, because setting
|
||||||
|
// NSPrintLastPage makes the print dialog pre-select the option to only
|
||||||
|
// print a range.
|
||||||
|
|
||||||
// We deliberately don't feed max_pages into the dialog, because setting
|
// TODO(stuartmorgan): implement 'print selection only' (probably requires
|
||||||
// NSPrintLastPage makes the print dialog pre-select the option to only print
|
// adding a new custom view to the panel on 10.5; 10.6 has
|
||||||
// a range.
|
// NSPrintPanelShowsPrintSelection).
|
||||||
|
NSPrintPanel* panel = [NSPrintPanel printPanel];
|
||||||
|
NSPrintInfo* printInfo = print_info_.get();
|
||||||
|
|
||||||
// TODO(stuartmorgan): implement 'print selection only' (probably requires
|
NSPrintPanelOptions options = [panel options];
|
||||||
// adding a new custom view to the panel on 10.5; 10.6 has
|
options |= NSPrintPanelShowsPaperSize;
|
||||||
// NSPrintPanelShowsPrintSelection).
|
options |= NSPrintPanelShowsOrientation;
|
||||||
NSPrintPanel* panel = [NSPrintPanel printPanel];
|
options |= NSPrintPanelShowsScaling;
|
||||||
NSPrintInfo* printInfo = print_info_.get();
|
[panel setOptions:options];
|
||||||
|
|
||||||
NSPrintPanelOptions options = [panel options];
|
// Set the print job title text.
|
||||||
options |= NSPrintPanelShowsPaperSize;
|
gfx::NativeView parent_view = delegate_->GetParentView();
|
||||||
options |= NSPrintPanelShowsOrientation;
|
if (parent_view) {
|
||||||
options |= NSPrintPanelShowsScaling;
|
NSString* job_title = [[parent_view.GetNativeNSView() window] title];
|
||||||
[panel setOptions:options];
|
if (job_title) {
|
||||||
|
PMPrintSettings printSettings =
|
||||||
// Set the print job title text.
|
(PMPrintSettings)[printInfo PMPrintSettings];
|
||||||
gfx::NativeView parent_view = delegate_->GetParentView();
|
PMPrintSettingsSetJobName(printSettings, (CFStringRef)job_title);
|
||||||
if (parent_view) {
|
[printInfo updateFromPMPrintSettings];
|
||||||
NSString* job_title = [[parent_view.GetNativeNSView() window] title];
|
}
|
||||||
if (job_title) {
|
|
||||||
PMPrintSettings printSettings =
|
|
||||||
(PMPrintSettings)[printInfo PMPrintSettings];
|
|
||||||
PMPrintSettingsSetJobName(printSettings, (CFStringRef)job_title);
|
|
||||||
[printInfo updateFromPMPrintSettings];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(stuartmorgan): We really want a tab sheet here, not a modal window.
|
||||||
|
// Will require restructuring the PrintingContext API to use a callback.
|
||||||
|
|
||||||
|
// This function may be called in the middle of a CATransaction, where
|
||||||
|
// running a modal panel is forbidden. That situation isn't ideal, but from
|
||||||
|
// this code's POV the right answer is to defer running the panel until
|
||||||
|
// after the current transaction. See https://crbug.com/849538.
|
||||||
|
__block auto block_callback = std::move(callback);
|
||||||
|
[CATransaction setCompletionBlock:^{
|
||||||
|
NSInteger selection = [panel runModalWithPrintInfo:printInfo];
|
||||||
|
if (selection == NSOKButton) {
|
||||||
|
print_info_.reset([[panel printInfo] retain]);
|
||||||
|
settings_->set_ranges(GetPageRangesFromPrintInfo());
|
||||||
|
InitPrintSettingsFromPrintInfo();
|
||||||
|
std::move(block_callback).Run(OK);
|
||||||
|
} else {
|
||||||
|
std::move(block_callback).Run(CANCEL);
|
||||||
|
}
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(stuartmorgan): We really want a tab sheet here, not a modal window.
|
|
||||||
// Will require restructuring the PrintingContext API to use a callback.
|
|
||||||
|
|
||||||
// This function may be called in the middle of a CATransaction, where
|
|
||||||
// running a modal panel is forbidden. That situation isn't ideal, but from
|
|
||||||
// this code's POV the right answer is to defer running the panel until after
|
|
||||||
// the current transaction. See https://crbug.com/849538.
|
|
||||||
__block auto block_callback = std::move(callback);
|
|
||||||
[CATransaction setCompletionBlock:^{
|
|
||||||
NSInteger selection = [panel runModalWithPrintInfo:printInfo];
|
|
||||||
if (selection == NSOKButton) {
|
|
||||||
print_info_.reset([[panel printInfo] retain]);
|
|
||||||
settings_->set_ranges(GetPageRangesFromPrintInfo());
|
|
||||||
InitPrintSettingsFromPrintInfo();
|
|
||||||
std::move(block_callback).Run(OK);
|
|
||||||
} else {
|
|
||||||
std::move(block_callback).Run(CANCEL);
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Size PrintingContextMac::GetPdfPaperSizeDeviceUnits() {
|
gfx::Size PrintingContextMac::GetPdfPaperSizeDeviceUnits() {
|
||||||
|
@@ -7,61 +7,58 @@
|
|||||||
#include <Foundation/Foundation.h>
|
#include <Foundation/Foundation.h>
|
||||||
|
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#import "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#import "third_party/breakpad/breakpad/src/client/mac/Framework/Breakpad.h"
|
#import "third_party/breakpad/breakpad/src/client/mac/Framework/Breakpad.h"
|
||||||
|
|
||||||
namespace remoting {
|
namespace remoting {
|
||||||
|
|
||||||
void InitializeCrashReporting() {
|
void InitializeCrashReporting() {
|
||||||
base::mac::ScopedNSAutoreleasePool autorelease_pool;
|
@autoreleasepool {
|
||||||
|
NSBundle* main_bundle = [NSBundle mainBundle];
|
||||||
|
|
||||||
NSBundle* main_bundle = [NSBundle mainBundle];
|
// Tell Breakpad where crash_inspector and crash_report_sender are.
|
||||||
|
NSString* resource_path = [main_bundle resourcePath];
|
||||||
|
NSString* inspector_location =
|
||||||
|
[resource_path stringByAppendingPathComponent:@"crash_inspector"];
|
||||||
|
NSString* reporter_bundle_location = [resource_path
|
||||||
|
stringByAppendingPathComponent:@"crash_report_sender.app"];
|
||||||
|
NSString* reporter_location =
|
||||||
|
[[NSBundle bundleWithPath:reporter_bundle_location] executablePath];
|
||||||
|
|
||||||
// Tell Breakpad where crash_inspector and crash_report_sender are.
|
NSDictionary* info_dictionary = [main_bundle infoDictionary];
|
||||||
NSString* resource_path = [main_bundle resourcePath];
|
NSMutableDictionary* breakpad_config =
|
||||||
NSString* inspector_location =
|
[[info_dictionary mutableCopy] autorelease];
|
||||||
[resource_path stringByAppendingPathComponent:@"crash_inspector"];
|
[breakpad_config setObject:inspector_location
|
||||||
NSString* reporter_bundle_location =
|
forKey:@BREAKPAD_INSPECTOR_LOCATION];
|
||||||
[resource_path stringByAppendingPathComponent:@"crash_report_sender.app"];
|
[breakpad_config setObject:reporter_location
|
||||||
NSString* reporter_location =
|
forKey:@BREAKPAD_REPORTER_EXE_LOCATION];
|
||||||
[[NSBundle bundleWithPath:reporter_bundle_location] executablePath];
|
|
||||||
|
|
||||||
NSDictionary* info_dictionary = [main_bundle infoDictionary];
|
// Configure Breakpad settings here, if they are not already customized in
|
||||||
NSMutableDictionary* breakpad_config =
|
// the Info.plist. These settings should be added to the plist, but the
|
||||||
[[info_dictionary mutableCopy] autorelease];
|
// problem is that the Breakpad URL contains a double-slash, which is broken
|
||||||
[breakpad_config setObject:inspector_location
|
// by the INFOPLIST_PREPROCESS step.
|
||||||
forKey:@BREAKPAD_INSPECTOR_LOCATION];
|
// TODO(lambroslambrou): Add these to the Info.plist, similarly to what is
|
||||||
[breakpad_config setObject:reporter_location
|
// done for Chrome Framework - see 'Tweak Info.plist' in
|
||||||
forKey:@BREAKPAD_REPORTER_EXE_LOCATION];
|
// chrome/chrome_dll_bundle.gypi.
|
||||||
|
if (![breakpad_config objectForKey:@BREAKPAD_SKIP_CONFIRM]) {
|
||||||
|
// Skip the upload confirmation dialog, since this is a remote-access
|
||||||
|
// service that shouldn't rely on a console user to dismiss any prompt.
|
||||||
|
// Also, this may be running in the LoginWindow context, where prompting
|
||||||
|
// might not be possible.
|
||||||
|
[breakpad_config setObject:@"YES" forKey:@BREAKPAD_SKIP_CONFIRM];
|
||||||
|
}
|
||||||
|
if (![breakpad_config objectForKey:@BREAKPAD_REPORT_INTERVAL]) {
|
||||||
|
// Set a minimum 6-hour interval between crash-reports, to match the
|
||||||
|
// throttling used on Windows.
|
||||||
|
[breakpad_config setObject:@"21600" forKey:@BREAKPAD_REPORT_INTERVAL];
|
||||||
|
}
|
||||||
|
if (![breakpad_config objectForKey:@BREAKPAD_URL]) {
|
||||||
|
[breakpad_config setObject:@"https://clients2.google.com/cr/report"
|
||||||
|
forKey:@BREAKPAD_URL];
|
||||||
|
}
|
||||||
|
|
||||||
// Configure Breakpad settings here, if they are not already customized in
|
if (!BreakpadCreate(breakpad_config)) {
|
||||||
// the Info.plist. These settings should be added to the plist, but the
|
LOG(ERROR) << "Breakpad initialization failed";
|
||||||
// problem is that the Breakpad URL contains a double-slash, which is broken
|
}
|
||||||
// by the INFOPLIST_PREPROCESS step.
|
|
||||||
// TODO(lambroslambrou): Add these to the Info.plist, similarly to what is
|
|
||||||
// done for Chrome Framework - see 'Tweak Info.plist' in
|
|
||||||
// chrome/chrome_dll_bundle.gypi.
|
|
||||||
if (![breakpad_config objectForKey:@BREAKPAD_SKIP_CONFIRM]) {
|
|
||||||
// Skip the upload confirmation dialog, since this is a remote-access
|
|
||||||
// service that shouldn't rely on a console user to dismiss any prompt.
|
|
||||||
// Also, this may be running in the LoginWindow context, where prompting
|
|
||||||
// might not be possible.
|
|
||||||
[breakpad_config setObject:@"YES"
|
|
||||||
forKey:@BREAKPAD_SKIP_CONFIRM];
|
|
||||||
}
|
|
||||||
if (![breakpad_config objectForKey:@BREAKPAD_REPORT_INTERVAL]) {
|
|
||||||
// Set a minimum 6-hour interval between crash-reports, to match the
|
|
||||||
// throttling used on Windows.
|
|
||||||
[breakpad_config setObject:@"21600"
|
|
||||||
forKey:@BREAKPAD_REPORT_INTERVAL];
|
|
||||||
}
|
|
||||||
if (![breakpad_config objectForKey:@BREAKPAD_URL]) {
|
|
||||||
[breakpad_config setObject:@"https://clients2.google.com/cr/report"
|
|
||||||
forKey:@BREAKPAD_URL];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!BreakpadCreate(breakpad_config)) {
|
|
||||||
LOG(ERROR) << "Breakpad initialization failed";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
@@ -62,17 +61,19 @@ ContinueWindowMac::~ContinueWindowMac() {
|
|||||||
void ContinueWindowMac::ShowUi() {
|
void ContinueWindowMac::ShowUi() {
|
||||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||||
|
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
controller_.reset(
|
controller_.reset(
|
||||||
[[ContinueWindowMacController alloc] initWithWindow:this]);
|
[[ContinueWindowMacController alloc] initWithWindow:this]);
|
||||||
[controller_ show];
|
[controller_ show];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContinueWindowMac::HideUi() {
|
void ContinueWindowMac::HideUi() {
|
||||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||||
|
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
[controller_ hide];
|
[controller_ hide];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@@ -14,7 +14,6 @@
|
|||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
#include "base/i18n/message_formatter.h"
|
#include "base/i18n/message_formatter.h"
|
||||||
#include "base/location.h"
|
#include "base/location.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
@@ -76,8 +75,9 @@ It2MeConfirmationDialogMac::~It2MeConfirmationDialogMac() {
|
|||||||
dialog_timer_.Stop();
|
dialog_timer_.Stop();
|
||||||
|
|
||||||
if (controller_) {
|
if (controller_) {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
[controller_ hide];
|
[controller_ hide];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,20 +92,22 @@ void It2MeConfirmationDialogMac::Show(const std::string& remote_user_email,
|
|||||||
ResultCallback dialog_action_callback = base::Bind(
|
ResultCallback dialog_action_callback = base::Bind(
|
||||||
&It2MeConfirmationDialogMac::OnDialogAction, base::Unretained(this));
|
&It2MeConfirmationDialogMac::OnDialogAction, base::Unretained(this));
|
||||||
|
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
controller_.reset([[It2MeConfirmationDialogMacController alloc]
|
controller_.reset([[It2MeConfirmationDialogMacController alloc]
|
||||||
initWithCallback:dialog_action_callback
|
initWithCallback:dialog_action_callback
|
||||||
username:remote_user_email]);
|
username:remote_user_email]);
|
||||||
[controller_ show];
|
[controller_ show];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void It2MeConfirmationDialogMac::OnDialogAction(Result result) {
|
void It2MeConfirmationDialogMac::OnDialogAction(Result result) {
|
||||||
dialog_timer_.Stop();
|
dialog_timer_.Stop();
|
||||||
|
|
||||||
if (controller_) {
|
if (controller_) {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
[controller_ hide];
|
[controller_ hide];
|
||||||
controller_.reset();
|
controller_.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result_callback_) {
|
if (result_callback_) {
|
||||||
|
@@ -353,15 +353,15 @@ RlzValueStore* ScopedRlzValueStoreLock::GetStore() {
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
void SetRlzStoreDirectory(const base::FilePath& directory) {
|
void SetRlzStoreDirectory(const base::FilePath& directory) {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
|
[g_test_folder release];
|
||||||
[g_test_folder release];
|
if (directory.empty()) {
|
||||||
if (directory.empty()) {
|
g_test_folder = nil;
|
||||||
g_test_folder = nil;
|
} else {
|
||||||
} else {
|
// Not Unsafe on OS X.
|
||||||
// Not Unsafe on OS X.
|
g_test_folder = [[NSString alloc]
|
||||||
g_test_folder =
|
initWithUTF8String:directory.AsUTF8Unsafe().c_str()];
|
||||||
[[NSString alloc] initWithUTF8String:directory.AsUTF8Unsafe().c_str()];
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "base/memory/ptr_util.h"
|
#include "base/memory/ptr_util.h"
|
||||||
@@ -45,71 +44,73 @@ class CoreWlanApi : public WifiDataProviderCommon::WlanApiInterface {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool CoreWlanApi::GetAccessPointData(WifiData::AccessPointDataSet* data) {
|
bool CoreWlanApi::GetAccessPointData(WifiData::AccessPointDataSet* data) {
|
||||||
base::mac::ScopedNSAutoreleasePool auto_pool;
|
@autoreleasepool { // Initialize the scan parameters with scan key merging
|
||||||
// Initialize the scan parameters with scan key merging disabled, so we get
|
// disabled, so we get
|
||||||
// every AP listed in the scan without any SSID de-duping logic.
|
// every AP listed in the scan without any SSID de-duping logic.
|
||||||
NSDictionary* params = @{ kCWScanKeyMerge : @NO };
|
NSDictionary* params = @{kCWScanKeyMerge : @NO};
|
||||||
|
|
||||||
NSSet* supported_interfaces = [CWInterface interfaceNames];
|
NSSet* supported_interfaces = [CWInterface interfaceNames];
|
||||||
NSUInteger interface_error_count = 0;
|
NSUInteger interface_error_count = 0;
|
||||||
for (NSString* interface_name in supported_interfaces) {
|
for (NSString* interface_name in supported_interfaces) {
|
||||||
CWInterface* corewlan_interface =
|
CWInterface* corewlan_interface =
|
||||||
[CWInterface interfaceWithName:interface_name];
|
[CWInterface interfaceWithName:interface_name];
|
||||||
if (!corewlan_interface) {
|
if (!corewlan_interface) {
|
||||||
DLOG(WARNING) << interface_name << ": initWithName failed";
|
DLOG(WARNING) << interface_name << ": initWithName failed";
|
||||||
++interface_error_count;
|
++interface_error_count;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const base::TimeTicks start_time = base::TimeTicks::Now();
|
||||||
|
|
||||||
|
NSError* err = nil;
|
||||||
|
NSArray* scan = [corewlan_interface scanForNetworksWithParameters:params
|
||||||
|
error:&err];
|
||||||
|
const int error_code = [err code];
|
||||||
|
const int count = [scan count];
|
||||||
|
// We could get an error code but count != 0 if the scan was interrupted,
|
||||||
|
// for example. For our purposes this is not fatal, so process as normal.
|
||||||
|
if (error_code && count == 0) {
|
||||||
|
DLOG(WARNING) << interface_name << ": CoreWLAN scan failed with error "
|
||||||
|
<< error_code;
|
||||||
|
++interface_error_count;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const base::TimeDelta duration = base::TimeTicks::Now() - start_time;
|
||||||
|
|
||||||
|
UMA_HISTOGRAM_CUSTOM_TIMES("Net.Wifi.ScanLatency", duration,
|
||||||
|
base::TimeDelta::FromMilliseconds(1),
|
||||||
|
base::TimeDelta::FromMinutes(1), 100);
|
||||||
|
|
||||||
|
DVLOG(1) << interface_name << ": found " << count << " wifi APs";
|
||||||
|
|
||||||
|
for (CWNetwork* network in scan) {
|
||||||
|
DCHECK(network);
|
||||||
|
AccessPointData access_point_data;
|
||||||
|
// -[CWNetwork bssid] uses colons to separate the components of the MAC
|
||||||
|
// address, but AccessPointData requires they be separated with a dash.
|
||||||
|
access_point_data.mac_address = base::SysNSStringToUTF16(
|
||||||
|
[[network bssid] stringByReplacingOccurrencesOfString:@":"
|
||||||
|
withString:@"-"]);
|
||||||
|
access_point_data.radio_signal_strength = [network rssiValue];
|
||||||
|
access_point_data.channel = [[network wlanChannel] channelNumber];
|
||||||
|
access_point_data.signal_to_noise =
|
||||||
|
access_point_data.radio_signal_strength -
|
||||||
|
[network noiseMeasurement];
|
||||||
|
access_point_data.ssid = base::SysNSStringToUTF16([network ssid]);
|
||||||
|
data->insert(access_point_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const base::TimeTicks start_time = base::TimeTicks::Now();
|
UMA_HISTOGRAM_CUSTOM_COUNTS(
|
||||||
|
"Net.Wifi.InterfaceCount",
|
||||||
|
[supported_interfaces count] - interface_error_count, 1, 5, 6);
|
||||||
|
|
||||||
NSError* err = nil;
|
// Return true even if some interfaces failed to scan, so long as at least
|
||||||
NSArray* scan =
|
// one interface did not fail.
|
||||||
[corewlan_interface scanForNetworksWithParameters:params error:&err];
|
return interface_error_count == 0 ||
|
||||||
const int error_code = [err code];
|
[supported_interfaces count] > interface_error_count;
|
||||||
const int count = [scan count];
|
|
||||||
// We could get an error code but count != 0 if the scan was interrupted,
|
|
||||||
// for example. For our purposes this is not fatal, so process as normal.
|
|
||||||
if (error_code && count == 0) {
|
|
||||||
DLOG(WARNING) << interface_name << ": CoreWLAN scan failed with error "
|
|
||||||
<< error_code;
|
|
||||||
++interface_error_count;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const base::TimeDelta duration = base::TimeTicks::Now() - start_time;
|
|
||||||
|
|
||||||
UMA_HISTOGRAM_CUSTOM_TIMES("Net.Wifi.ScanLatency", duration,
|
|
||||||
base::TimeDelta::FromMilliseconds(1),
|
|
||||||
base::TimeDelta::FromMinutes(1), 100);
|
|
||||||
|
|
||||||
DVLOG(1) << interface_name << ": found " << count << " wifi APs";
|
|
||||||
|
|
||||||
for (CWNetwork* network in scan) {
|
|
||||||
DCHECK(network);
|
|
||||||
AccessPointData access_point_data;
|
|
||||||
// -[CWNetwork bssid] uses colons to separate the components of the MAC
|
|
||||||
// address, but AccessPointData requires they be separated with a dash.
|
|
||||||
access_point_data.mac_address = base::SysNSStringToUTF16([[network bssid]
|
|
||||||
stringByReplacingOccurrencesOfString:@":"
|
|
||||||
withString:@"-"]);
|
|
||||||
access_point_data.radio_signal_strength = [network rssiValue];
|
|
||||||
access_point_data.channel = [[network wlanChannel] channelNumber];
|
|
||||||
access_point_data.signal_to_noise =
|
|
||||||
access_point_data.radio_signal_strength - [network noiseMeasurement];
|
|
||||||
access_point_data.ssid = base::SysNSStringToUTF16([network ssid]);
|
|
||||||
data->insert(access_point_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UMA_HISTOGRAM_CUSTOM_COUNTS(
|
|
||||||
"Net.Wifi.InterfaceCount",
|
|
||||||
[supported_interfaces count] - interface_error_count, 1, 5, 6);
|
|
||||||
|
|
||||||
// Return true even if some interfaces failed to scan, so long as at least
|
|
||||||
// one interface did not fail.
|
|
||||||
return interface_error_count == 0 ||
|
|
||||||
[supported_interfaces count] > interface_error_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The time periods, in milliseconds, between successive polls of the wifi data.
|
// The time periods, in milliseconds, between successive polls of the wifi data.
|
||||||
|
@@ -26,7 +26,6 @@
|
|||||||
#include "base/mac/mac_util.h"
|
#include "base/mac/mac_util.h"
|
||||||
#include "base/mac/mach_port_rendezvous.h"
|
#include "base/mac/mach_port_rendezvous.h"
|
||||||
#include "base/mac/scoped_cftyperef.h"
|
#include "base/mac/scoped_cftyperef.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
#include "base/rand_util.h"
|
#include "base/rand_util.h"
|
||||||
#include "base/stl_util.h"
|
#include "base/stl_util.h"
|
||||||
@@ -83,56 +82,57 @@ const char* SandboxMac::kSandboxBundleVersionPath = "BUNDLE_VERSION_PATH";
|
|||||||
void SandboxMac::Warmup(SandboxType sandbox_type) {
|
void SandboxMac::Warmup(SandboxType sandbox_type) {
|
||||||
DCHECK_EQ(sandbox_type, SANDBOX_TYPE_GPU);
|
DCHECK_EQ(sandbox_type, SANDBOX_TYPE_GPU);
|
||||||
|
|
||||||
base::mac::ScopedNSAutoreleasePool scoped_pool;
|
@autoreleasepool {
|
||||||
|
{ // CGColorSpaceCreateWithName(), CGBitmapContextCreate() - 10.5.6
|
||||||
|
base::ScopedCFTypeRef<CGColorSpaceRef> rgb_colorspace(
|
||||||
|
CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB));
|
||||||
|
|
||||||
{ // CGColorSpaceCreateWithName(), CGBitmapContextCreate() - 10.5.6
|
// Allocate a 1x1 image.
|
||||||
base::ScopedCFTypeRef<CGColorSpaceRef> rgb_colorspace(
|
char data[4];
|
||||||
CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB));
|
base::ScopedCFTypeRef<CGContextRef> context(CGBitmapContextCreate(
|
||||||
|
data, 1, 1, 8, 1 * 4, rgb_colorspace,
|
||||||
|
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
|
||||||
|
|
||||||
// Allocate a 1x1 image.
|
// Load in the color profiles we'll need (as a side effect).
|
||||||
char data[4];
|
ignore_result(base::mac::GetSRGBColorSpace());
|
||||||
base::ScopedCFTypeRef<CGContextRef> context(CGBitmapContextCreate(
|
ignore_result(base::mac::GetSystemColorSpace());
|
||||||
data, 1, 1, 8, 1 * 4, rgb_colorspace,
|
|
||||||
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
|
|
||||||
|
|
||||||
// Load in the color profiles we'll need (as a side effect).
|
// CGColorSpaceCreateSystemDefaultCMYK - 10.6
|
||||||
ignore_result(base::mac::GetSRGBColorSpace());
|
base::ScopedCFTypeRef<CGColorSpaceRef> cmyk_colorspace(
|
||||||
ignore_result(base::mac::GetSystemColorSpace());
|
CGColorSpaceCreateWithName(kCGColorSpaceGenericCMYK));
|
||||||
|
}
|
||||||
|
|
||||||
// CGColorSpaceCreateSystemDefaultCMYK - 10.6
|
{ // localtime() - 10.5.6
|
||||||
base::ScopedCFTypeRef<CGColorSpaceRef> cmyk_colorspace(
|
time_t tv = {0};
|
||||||
CGColorSpaceCreateWithName(kCGColorSpaceGenericCMYK));
|
localtime(&tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // localtime() - 10.5.6
|
{ // Gestalt() tries to read
|
||||||
time_t tv = {0};
|
// /System/Library/CoreServices/SystemVersion.plist
|
||||||
localtime(&tv);
|
// on 10.5.6
|
||||||
}
|
int32_t tmp;
|
||||||
|
base::SysInfo::OperatingSystemVersionNumbers(&tmp, &tmp, &tmp);
|
||||||
|
}
|
||||||
|
|
||||||
{ // Gestalt() tries to read /System/Library/CoreServices/SystemVersion.plist
|
{ // CGImageSourceGetStatus() - 10.6
|
||||||
// on 10.5.6
|
// Create a png with just enough data to get everything warmed up...
|
||||||
int32_t tmp;
|
char png_header[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
|
||||||
base::SysInfo::OperatingSystemVersionNumbers(&tmp, &tmp, &tmp);
|
NSData* data = [NSData dataWithBytes:png_header
|
||||||
}
|
length:base::size(png_header)];
|
||||||
|
base::ScopedCFTypeRef<CGImageSourceRef> img(
|
||||||
|
CGImageSourceCreateWithData((CFDataRef)data, NULL));
|
||||||
|
CGImageSourceGetStatus(img);
|
||||||
|
}
|
||||||
|
|
||||||
{ // CGImageSourceGetStatus() - 10.6
|
{
|
||||||
// Create a png with just enough data to get everything warmed up...
|
// Allow access to /dev/urandom.
|
||||||
char png_header[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
|
base::GetUrandomFD();
|
||||||
NSData* data = [NSData dataWithBytes:png_header
|
}
|
||||||
length:base::size(png_header)];
|
|
||||||
base::ScopedCFTypeRef<CGImageSourceRef> img(
|
|
||||||
CGImageSourceCreateWithData((CFDataRef)data, NULL));
|
|
||||||
CGImageSourceGetStatus(img);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{ // IOSurfaceLookup() - 10.7
|
||||||
// Allow access to /dev/urandom.
|
// Needed by zero-copy texture update framework - crbug.com/323338
|
||||||
base::GetUrandomFD();
|
base::ScopedCFTypeRef<IOSurfaceRef> io_surface(IOSurfaceLookup(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // IOSurfaceLookup() - 10.7
|
|
||||||
// Needed by zero-copy texture update framework - crbug.com/323338
|
|
||||||
base::ScopedCFTypeRef<IOSurfaceRef> io_surface(IOSurfaceLookup(0));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -212,8 +212,7 @@ void CocoaTest::TearDown() {
|
|||||||
([start_date timeIntervalSinceNow] > -kCloseTimeoutSeconds);
|
([start_date timeIntervalSinceNow] > -kCloseTimeoutSeconds);
|
||||||
|
|
||||||
// Autorelease anything thrown up by the event loop.
|
// Autorelease anything thrown up by the event loop.
|
||||||
{
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
++spins;
|
++spins;
|
||||||
NSEvent* next_event = [NSApp nextEventMatchingMask:NSAnyEventMask
|
NSEvent* next_event = [NSApp nextEventMatchingMask:NSAnyEventMask
|
||||||
untilDate:nil
|
untilDate:nil
|
||||||
@@ -253,12 +252,13 @@ std::set<NSWindow*> CocoaTest::ApplicationWindows() {
|
|||||||
|
|
||||||
// Must create a pool here because [NSApp windows] has created an array
|
// Must create a pool here because [NSApp windows] has created an array
|
||||||
// with retains on all the windows in it.
|
// with retains on all the windows in it.
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
@autoreleasepool {
|
||||||
NSArray* appWindows = [NSApp windows];
|
NSArray* appWindows = [NSApp windows];
|
||||||
for (NSWindow* window in appWindows) {
|
for (NSWindow* window in appWindows) {
|
||||||
windows.insert(window);
|
windows.insert(window);
|
||||||
|
}
|
||||||
|
return windows;
|
||||||
}
|
}
|
||||||
return windows;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<NSWindow*> CocoaTest::WindowsLeft() {
|
std::set<NSWindow*> CocoaTest::WindowsLeft() {
|
||||||
|
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#import "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#import "base/mac/scoped_nsobject.h"
|
#import "base/mac/scoped_nsobject.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#import "testing/gtest_mac.h"
|
#import "testing/gtest_mac.h"
|
||||||
@@ -220,8 +219,7 @@ TEST_F(NativeViewHostMacTest, NativeViewHidden) {
|
|||||||
// Check that we can destroy cleanly even if the native view has already been
|
// Check that we can destroy cleanly even if the native view has already been
|
||||||
// released.
|
// released.
|
||||||
TEST_F(NativeViewHostMacTest, NativeViewReleased) {
|
TEST_F(NativeViewHostMacTest, NativeViewReleased) {
|
||||||
{
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
CreateHost();
|
CreateHost();
|
||||||
// In practice the native view is a WebContentsViewCocoa which is retained
|
// In practice the native view is a WebContentsViewCocoa which is retained
|
||||||
// by its superview (a TabContentsContainerView) and by WebContentsViewMac.
|
// by its superview (a TabContentsContainerView) and by WebContentsViewMac.
|
||||||
|
@@ -7,7 +7,6 @@
|
|||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
#import "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#include "ui/base/test/scoped_fake_full_keyboard_access.h"
|
#include "ui/base/test/scoped_fake_full_keyboard_access.h"
|
||||||
#include "ui/base/test/scoped_fake_nswindow_focus.h"
|
#include "ui/base/test/scoped_fake_nswindow_focus.h"
|
||||||
#include "ui/base/test/scoped_fake_nswindow_fullscreen.h"
|
#include "ui/base/test/scoped_fake_nswindow_fullscreen.h"
|
||||||
@@ -63,13 +62,14 @@ void ViewsTestHelperMac::TearDown() {
|
|||||||
// this is handled automatically by views::Widget::CloseAllSecondaryWidgets().
|
// this is handled automatically by views::Widget::CloseAllSecondaryWidgets().
|
||||||
// Unit tests on Aura may create Widgets owned by a RootWindow that gets torn
|
// Unit tests on Aura may create Widgets owned by a RootWindow that gets torn
|
||||||
// down, but on Mac we need to be more explicit.
|
// down, but on Mac we need to be more explicit.
|
||||||
base::mac::ScopedNSAutoreleasePool pool; // Ensure the NSArray is released.
|
@autoreleasepool {
|
||||||
NSArray* native_windows = [NSApp windows];
|
NSArray* native_windows = [NSApp windows];
|
||||||
for (NSWindow* window : native_windows)
|
for (NSWindow* window : native_windows)
|
||||||
DCHECK(!Widget::GetWidgetForNativeWindow(window)) << "Widget not closed.";
|
DCHECK(!Widget::GetWidgetForNativeWindow(window)) << "Widget not closed.";
|
||||||
|
|
||||||
ui::test::EventGeneratorDelegate::SetFactoryFunction(
|
ui::test::EventGeneratorDelegate::SetFactoryFunction(
|
||||||
ui::test::EventGeneratorDelegate::FactoryFunction());
|
ui::test::EventGeneratorDelegate::FactoryFunction());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace views
|
} // namespace views
|
||||||
|
@@ -10,7 +10,6 @@
|
|||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
#import "base/mac/foundation_util.h"
|
#import "base/mac/foundation_util.h"
|
||||||
#include "base/mac/mac_util.h"
|
#include "base/mac/mac_util.h"
|
||||||
#import "base/mac/scoped_nsautorelease_pool.h"
|
|
||||||
#import "base/mac/scoped_nsobject.h"
|
#import "base/mac/scoped_nsobject.h"
|
||||||
#import "base/mac/scoped_objc_class_swizzler.h"
|
#import "base/mac/scoped_objc_class_swizzler.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
@@ -817,10 +816,9 @@ TEST_F(NativeWidgetMacTest, NonWidgetParent) {
|
|||||||
TEST_F(NativeWidgetMacTest, CloseAllSecondaryWidgetsValidState) {
|
TEST_F(NativeWidgetMacTest, CloseAllSecondaryWidgetsValidState) {
|
||||||
NativeWidgetMacTestWindow* last_window = nil;
|
NativeWidgetMacTestWindow* last_window = nil;
|
||||||
bool window_deallocated = false;
|
bool window_deallocated = false;
|
||||||
{
|
@autoreleasepool {
|
||||||
// First verify the behavior of CloseAllSecondaryWidgets in the normal case,
|
// First verify the behavior of CloseAllSecondaryWidgets in the normal case,
|
||||||
// and how [NSApp windows] changes in response to Widget closure.
|
// and how [NSApp windows] changes in response to Widget closure.
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
Widget* widget = CreateWidgetWithTestWindow(
|
Widget* widget = CreateWidgetWithTestWindow(
|
||||||
Widget::InitParams(Widget::InitParams::TYPE_WINDOW), &last_window);
|
Widget::InitParams(Widget::InitParams::TYPE_WINDOW), &last_window);
|
||||||
last_window.deallocFlag = &window_deallocated;
|
last_window.deallocFlag = &window_deallocated;
|
||||||
@@ -833,10 +831,9 @@ TEST_F(NativeWidgetMacTest, CloseAllSecondaryWidgetsValidState) {
|
|||||||
EXPECT_TRUE(window_deallocated);
|
EXPECT_TRUE(window_deallocated);
|
||||||
window_deallocated = false;
|
window_deallocated = false;
|
||||||
|
|
||||||
{
|
@autoreleasepool {
|
||||||
// Repeat, but now retain a reference and close the window before
|
// Repeat, but now retain a reference and close the window before
|
||||||
// CloseAllSecondaryWidgets().
|
// CloseAllSecondaryWidgets().
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
Widget* widget = CreateWidgetWithTestWindow(
|
Widget* widget = CreateWidgetWithTestWindow(
|
||||||
Widget::InitParams(Widget::InitParams::TYPE_WINDOW), &last_window);
|
Widget::InitParams(Widget::InitParams::TYPE_WINDOW), &last_window);
|
||||||
last_window.deallocFlag = &window_deallocated;
|
last_window.deallocFlag = &window_deallocated;
|
||||||
@@ -847,8 +844,7 @@ TEST_F(NativeWidgetMacTest, CloseAllSecondaryWidgetsValidState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_FALSE(window_deallocated);
|
EXPECT_FALSE(window_deallocated);
|
||||||
{
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
Widget::CloseAllSecondaryWidgets();
|
Widget::CloseAllSecondaryWidgets();
|
||||||
[last_window release];
|
[last_window release];
|
||||||
}
|
}
|
||||||
@@ -880,8 +876,7 @@ TEST_F(NativeWidgetMacTest, NonWidgetParentLastReference) {
|
|||||||
bool child_dealloced = false;
|
bool child_dealloced = false;
|
||||||
bool native_parent_dealloced = false;
|
bool native_parent_dealloced = false;
|
||||||
NativeWidgetMacTestWindow* native_parent = nil;
|
NativeWidgetMacTestWindow* native_parent = nil;
|
||||||
{
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
native_parent = MakeBorderlessNativeParent();
|
native_parent = MakeBorderlessNativeParent();
|
||||||
[native_parent setDeallocFlag:&native_parent_dealloced];
|
[native_parent setDeallocFlag:&native_parent_dealloced];
|
||||||
|
|
||||||
@@ -893,13 +888,12 @@ TEST_F(NativeWidgetMacTest, NonWidgetParentLastReference) {
|
|||||||
CreateWidgetWithTestWindow(std::move(init_params), &window);
|
CreateWidgetWithTestWindow(std::move(init_params), &window);
|
||||||
[window setDeallocFlag:&child_dealloced];
|
[window setDeallocFlag:&child_dealloced];
|
||||||
}
|
}
|
||||||
{
|
@autoreleasepool {
|
||||||
// On 10.11, closing a weak reference on the parent window works, but older
|
// On 10.11, closing a weak reference on the parent window works, but older
|
||||||
// versions of AppKit get upset if things are released inside -[NSWindow
|
// versions of AppKit get upset if things are released inside -[NSWindow
|
||||||
// close]. This test tries to establish a situation where the last reference
|
// close]. This test tries to establish a situation where the last reference
|
||||||
// to the child window is released inside WidgetOwnerNSWindowAdapter::
|
// to the child window is released inside WidgetOwnerNSWindowAdapter::
|
||||||
// OnWindowWillClose().
|
// OnWindowWillClose().
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
[native_parent close];
|
[native_parent close];
|
||||||
EXPECT_TRUE(child_dealloced);
|
EXPECT_TRUE(child_dealloced);
|
||||||
}
|
}
|
||||||
@@ -1511,8 +1505,7 @@ TEST_F(NativeWidgetMacTest, CloseWithWindowModalSheet) {
|
|||||||
|
|
||||||
// Test another hypothetical: What if -sheetDidEnd: was invoked somehow
|
// Test another hypothetical: What if -sheetDidEnd: was invoked somehow
|
||||||
// without going through [NSApp endSheet:] or -[NSWindow endSheet:].
|
// without going through [NSApp endSheet:] or -[NSWindow endSheet:].
|
||||||
{
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
Widget* sheet_widget = ShowWindowModalWidget(native_parent);
|
Widget* sheet_widget = ShowWindowModalWidget(native_parent);
|
||||||
NSWindow* sheet_window =
|
NSWindow* sheet_window =
|
||||||
sheet_widget->GetNativeWindow().GetNativeNSWindow();
|
sheet_widget->GetNativeWindow().GetNativeNSWindow();
|
||||||
@@ -1548,8 +1541,7 @@ TEST_F(NativeWidgetMacTest, CloseWithWindowModalSheet) {
|
|||||||
// https://crbug.com/851376.
|
// https://crbug.com/851376.
|
||||||
TEST_F(NativeWidgetMacTest, CloseWindowModalSheetWithoutSheetParent) {
|
TEST_F(NativeWidgetMacTest, CloseWindowModalSheetWithoutSheetParent) {
|
||||||
NSWindow* native_parent = MakeClosableTitledNativeParent();
|
NSWindow* native_parent = MakeClosableTitledNativeParent();
|
||||||
{
|
@autoreleasepool {
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
|
||||||
Widget* sheet_widget = ShowWindowModalWidget(native_parent);
|
Widget* sheet_widget = ShowWindowModalWidget(native_parent);
|
||||||
NSWindow* sheet_window =
|
NSWindow* sheet_window =
|
||||||
sheet_widget->GetNativeWindow().GetNativeNSWindow();
|
sheet_widget->GetNativeWindow().GetNativeNSWindow();
|
||||||
|
Reference in New Issue
Block a user