diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-23 12:08:18 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-23 12:08:18 +0000 |
commit | 8bb846f9fa618c1975638a49c3be7ec61f304d13 (patch) | |
tree | b9a089f61f1c9c709f82eea0dc7a030cee23c24f /chrome | |
parent | 9b78cfd2818651c50f76990771fdaae1d85c3c3d (diff) | |
download | chromium_src-8bb846f9fa618c1975638a49c3be7ec61f304d13.zip chromium_src-8bb846f9fa618c1975638a49c3be7ec61f304d13.tar.gz chromium_src-8bb846f9fa618c1975638a49c3be7ec61f304d13.tar.bz2 |
Adding `cause` to the cookie extension API's onchanged event signature.
This makes it simpler for developers to deal with the release/set event pair generated by setting a cookie that already exists, and gives them more information about general cookie removal (e.g. that the cookie wasn't "removed" actively but expired).
BUG=70101
TEST=net_unittests
Review URL: http://codereview.chromium.org/6698023
Patch from Mike West <mkwst@chromium.org>.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79113 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
9 files changed, 263 insertions, 48 deletions
diff --git a/chrome/browser/extensions/extension_cookies_api.cc b/chrome/browser/extensions/extension_cookies_api.cc index 3fcbdd2..c5d5f1d 100644 --- a/chrome/browser/extensions/extension_cookies_api.cc +++ b/chrome/browser/extensions/extension_cookies_api.cc @@ -62,6 +62,31 @@ void ExtensionCookiesEventRouter::CookieChanged( keys::kCookieKey, extension_cookies_helpers::CreateCookieValue(*details->cookie, extension_cookies_helpers::GetStoreIdFromProfile(profile))); + + // Map the interal cause to an external string. + std::string cause; + switch (details->cause) { + case net::CookieMonster::Delegate::CHANGE_COOKIE_EXPLICIT: + cause = keys::kExplicitChangeCause; + break; + + case net::CookieMonster::Delegate::CHANGE_COOKIE_OVERWRITE: + cause = keys::kOverwriteChangeCause; + break; + + case net::CookieMonster::Delegate::CHANGE_COOKIE_EXPIRED: + cause = keys::kExpiredChangeCause; + break; + + case net::CookieMonster::Delegate::CHANGE_COOKIE_EVICTED: + cause = keys::kEvictedChangeCause; + break; + + default: + NOTREACHED(); + } + dict->SetString(keys::kCauseKey, cause); + args.Append(dict); std::string json_args; diff --git a/chrome/browser/extensions/extension_cookies_api_constants.cc b/chrome/browser/extensions/extension_cookies_api_constants.cc index 6307079..b6d0ca3 100644 --- a/chrome/browser/extensions/extension_cookies_api_constants.cc +++ b/chrome/browser/extensions/extension_cookies_api_constants.cc @@ -6,6 +6,8 @@ namespace extension_cookies_api_constants { +// Keys +const char kCauseKey[] = "cause"; const char kCookieKey[] = "cookie"; const char kDomainKey[] = "domain"; const char kExpirationDateKey[] = "expirationDate"; @@ -22,8 +24,16 @@ const char kTabIdsKey[] = "tabIds"; const char kUrlKey[] = "url"; const char kValueKey[] = "value"; +// Cause Constants +extern const char kExplicitChangeCause[] = "explicit"; +extern const char kOverwriteChangeCause[] = "overwrite"; +extern const char kExpiredChangeCause[] = "expired"; +extern const char kEvictedChangeCause[] = "evicted"; + +// Events const char kOnChanged[] = "cookies.onChanged"; +// Errors const char kCookieSetFailedError[] = "Failed to parse or set cookie named \"*\"."; const char kInvalidStoreIdError[] = "Invalid cookie store id: \"*\"."; diff --git a/chrome/browser/extensions/extension_cookies_api_constants.h b/chrome/browser/extensions/extension_cookies_api_constants.h index 04b8035..73a977a 100644 --- a/chrome/browser/extensions/extension_cookies_api_constants.h +++ b/chrome/browser/extensions/extension_cookies_api_constants.h @@ -11,6 +11,7 @@ namespace extension_cookies_api_constants { // Keys. +extern const char kCauseKey[]; extern const char kCookieKey[]; extern const char kDomainKey[]; extern const char kExpirationDateKey[]; @@ -27,6 +28,12 @@ extern const char kTabIdsKey[]; extern const char kUrlKey[]; extern const char kValueKey[]; +// Cause Constants +extern const char kExplicitChangeCause[]; +extern const char kOverwriteChangeCause[]; +extern const char kExpiredChangeCause[]; +extern const char kEvictedChangeCause[]; + // Events. extern const char kOnChanged[]; diff --git a/chrome/browser/net/chrome_cookie_notification_details.h b/chrome/browser/net/chrome_cookie_notification_details.h index 57df427..96b32ce 100644 --- a/chrome/browser/net/chrome_cookie_notification_details.h +++ b/chrome/browser/net/chrome_cookie_notification_details.h @@ -11,13 +11,16 @@ struct ChromeCookieDetails { public: ChromeCookieDetails(const net::CookieMonster::CanonicalCookie* cookie_copy, - bool is_removed) + bool is_removed, + net::CookieMonster::Delegate::ChangeCause cause) : cookie(cookie_copy), - removed(is_removed) { + removed(is_removed), + cause(cause) { } const net::CookieMonster::CanonicalCookie* cookie; bool removed; + net::CookieMonster::Delegate::ChangeCause cause; }; #endif // CHROME_BROWSER_NET_CHROME_COOKIE_NOTIFICATION_DETAILS_H_ diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 69e6ba2..3b7e943 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc @@ -44,13 +44,15 @@ class ChromeCookieMonsterDelegate : public net::CookieMonster::Delegate { // net::CookieMonster::Delegate implementation. virtual void OnCookieChanged( const net::CookieMonster::CanonicalCookie& cookie, - bool removed) { + bool removed, + net::CookieMonster::Delegate::ChangeCause cause) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, NewRunnableMethod(this, &ChromeCookieMonsterDelegate::OnCookieChangedAsyncHelper, cookie, - removed)); + removed, + cause)); } private: @@ -103,9 +105,10 @@ class ChromeCookieMonsterDelegate : public net::CookieMonster::Delegate { void OnCookieChangedAsyncHelper( const net::CookieMonster::CanonicalCookie& cookie, - bool removed) { + bool removed, + net::CookieMonster::Delegate::ChangeCause cause) { if (profile_getter_->get()) { - ChromeCookieDetails cookie_details(&cookie, removed); + ChromeCookieDetails cookie_details(&cookie, removed, cause); NotificationService::current()->Notify( NotificationType::COOKIE_CHANGED, Source<Profile>(profile_getter_->get()), diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json index b4d72b5..6f38d37 100644 --- a/chrome/common/extensions/api/extension_api.json +++ b/chrome/common/extensions/api/extension_api.json @@ -194,6 +194,7 @@ "name": "isAllowedIncognitoAccess", "type": "function", "description": "Retrieves the state of the extension's access to Incognito-mode (as determined by the user-controlled 'Allowed in Incognito' checkbox.", + "min_version": "12.0.706.0", "parameters": [ { "type": "function", @@ -212,6 +213,7 @@ "name": "isAllowedFileSchemeAccess", "type": "function", "description": "Retrieves the state of the extension's access to the 'file://' scheme (as determined by the user-controlled 'Allow access to File URLs' checkbox.", + "min_version": "12.0.706.0", "parameters": [ { "type": "function", @@ -3227,6 +3229,7 @@ "type": "function", "name": "callback", "optional": true, + "min_version": "11.0.674.0", "parameters": [ { "name": "cookie", "$ref": "Cookie", "optional": true, "description": "Contains details about the cookie that's been set. If setting failed for any reason, this will be \"null\", and \"chrome.extension.lastError\" will be set." @@ -3254,6 +3257,7 @@ "type": "function", "name": "callback", "optional": true, + "min_version": "11.0.674.0", "parameters": [ { "name": "details", @@ -3291,14 +3295,15 @@ { "name": "onChanged", "type": "function", - "description": "Fired when a cookie is set or removed.", + "description": "Fired when a cookie is set or removed. As a special case, note that updating a cookie's properties is implemented as a two step process: the cookie to be updated is first removed entirely, generating a notification with \"cause\" of \"overwrite\" . Afterwards, a new cookie is written with the updated values, generating a second notification with \"cause\" \"explicit\".", "parameters": [ { "type": "object", "name": "changeInfo", "properties": { "removed": {"type": "boolean", "description": "True if a cookie was removed."}, - "cookie": {"$ref": "Cookie", "description": "Information about the cookie that was set or removed."} + "cookie": {"$ref": "Cookie", "description": "Information about the cookie that was set or removed."}, + "cause": {"min_version": "12.0.707.0", "type": "string", "enum": ["evicted", "expired", "explicit", "overwrite"], "description": "The underlying reason behind the cookie's change. If a cookie was inserted, or removed via an explicit call to \"chrome.cookies.remove\", \"cause\" will be \"explicit\". If a cookie was automatically removed due to expiry, \"cause\" will be \"expired\". If a cookie was automatically removed due to garbage collection, \"cause\" will be \"evicted\". If a cookie was automatically removed due to a \"set\" call that overwrote it, \"cause\" will be \"overwrite\". Plan your response accordingly."} } } ] diff --git a/chrome/common/extensions/docs/cookies.html b/chrome/common/extensions/docs/cookies.html index 14c8cf6..52a7236 100644 --- a/chrome/common/extensions/docs/cookies.html +++ b/chrome/common/extensions/docs/cookies.html @@ -2137,9 +2137,9 @@ see <a href="samples.html">Samples</a>. <dd style="display: none; "> Description of this parameter from the json schema. </dd> - <dd style="display: none; "> + <dd> This parameter was added in version - <b><span></span></b>. + <b><span>11.0.674.0</span></b>. You must omit this parameter in earlier versions, and you may omit it in any version. If you require this parameter, the manifest key @@ -3212,9 +3212,9 @@ see <a href="samples.html">Samples</a>. <dd style="display: none; "> Description of this parameter from the json schema. </dd> - <dd style="display: none; "> + <dd> This parameter was added in version - <b><span></span></b>. + <b><span>11.0.674.0</span></b>. You must omit this parameter in earlier versions, and you may omit it in any version. If you require this parameter, the manifest key @@ -3378,7 +3378,7 @@ see <a href="samples.html">Samples</a>. <div class="description"> <p class="todo" style="display: none; ">Undocumented.</p> - <p>Fired when a cookie is set or removed.</p> + <p>Fired when a cookie is set or removed. As a special case, note that updating a cookie's properties is implemented as a two step process: the cookie to be updated is first removed entirely, generating a notification with "cause" of "overwrite" . Afterwards, a new cookie is written with the updated values, generating a second notification with "cause" "explicit".</p> <!-- PARAMETERS --> <div> @@ -3567,6 +3567,74 @@ see <a href="samples.html">Samples</a>. </dd> </div> + </div><div> + <div> + <dt> + <var>cause</var> + <em> + + <!-- TYPE --> + <div style="display:inline"> + ( + <span class="optional" style="display: none; ">optional</span> + <span class="enum">enumerated</span> + <span id="typeTemplate"> + <span style="display: none; "> + <a> Type</a> + </span> + <span> + <span style="display: none; "> + array of <span><span></span></span> + </span> + <span>string</span> + <span>["evicted", "expired", "explicit", "overwrite"]</span> + </span> + </span> + ) + </div> + + </em> + </dt> + <dd class="todo" style="display: none; "> + Undocumented. + </dd> + <dd>The underlying reason behind the cookie's change. If a cookie was inserted, or removed via an explicit call to "chrome.cookies.remove", "cause" will be "explicit". If a cookie was automatically removed due to expiry, "cause" will be "expired". If a cookie was automatically removed due to garbage collection, "cause" will be "evicted". If a cookie was automatically removed due to a "set" call that overwrote it, "cause" will be "overwrite". Plan your response accordingly.</dd> + <dd> + This parameter was added in version + <b><span>12.0.707.0</span></b>. + You must omit this parameter in earlier versions, + and you may omit it in any version. If you require this + parameter, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </dd> + + <!-- OBJECT PROPERTIES --> + <dd style="display: none; "> + <dl> + <div> + <div> + </div> + </div> + </dl> + </dd> + + <!-- OBJECT METHODS --> + <dd style="display: none; "> + <div></div> + </dd> + + <!-- OBJECT EVENT FIELDS --> + <dd style="display: none; "> + <div></div> + </dd> + + <!-- FUNCTION PARAMETERS --> + <dd style="display: none; "> + <div></div> + </dd> + + </div> </div> </dl> </dd> diff --git a/chrome/common/extensions/docs/extension.html b/chrome/common/extensions/docs/extension.html index 149f08f..c8d6378 100644 --- a/chrome/common/extensions/docs/extension.html +++ b/chrome/common/extensions/docs/extension.html @@ -2004,8 +2004,8 @@ For details, see </div> <!-- MIN_VERSION --> - <p style="display: none; "> - This function was added in version <b><span></span></b>. + <p> + This function was added in version <b><span>12.0.706.0</span></b>. If you require this function, the manifest key <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> can ensure that your extension won't be run in an earlier browser version. @@ -2200,8 +2200,8 @@ For details, see </div> <!-- MIN_VERSION --> - <p style="display: none; "> - This function was added in version <b><span></span></b>. + <p> + This function was added in version <b><span>12.0.706.0</span></b>. If you require this function, the manifest key <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> can ensure that your extension won't be run in an earlier browser version. diff --git a/chrome/test/data/extensions/api_test/cookies/events/test.html b/chrome/test/data/extensions/api_test/cookies/events/test.html index a62217d..1015cb0 100644 --- a/chrome/test/data/extensions/api_test/cookies/events/test.html +++ b/chrome/test/data/extensions/api_test/cookies/events/test.html @@ -1,34 +1,128 @@ <script> -var setChangeComplete = chrome.test.callbackAdded(); -var removeChangeComplete = chrome.test.callbackAdded(); -var removeCallbackCalled = false; -chrome.cookies.onChanged.addListener(function (info) { - if (!info.removed && - info.cookie.name == 'test' && - info.cookie.value == '42' && - info.cookie.domain == 'a.com' && - info.cookie.hostOnly && - info.cookie.path == '/' && - !info.cookie.secure && - !info.cookie.httpOnly && - !info.cookie.session && - info.cookie.expirationDate == 12345678900 && - info.cookie.storeId == "0") { - setChangeComplete(); - } else if (info.removed) { - chrome.test.assertFalse(removeCallbackCalled, - "onChanged should fire before the chrome.cookies.remove callback."); - removeChangeComplete(); - } else { - chrome.test.notifyFail("Got an invalid cookie: " + JSON.stringify(info)); - } -}); -chrome.cookies.set({url: 'http://a.com/path', - name: 'test', - value: '42', - expirationDate: 12345678900}); +// These are the cookies we expect to see along the way. +var SET_REMOVE_COOKIE = { + name: 'testSetRemove', + value: '42', + domain: 'a.com', + hostOnly: true, + path: '/', + secure: false, + httpOnly: false, + session: false, + expirationDate: 12345678900, + storeId: "0" +}; + +var OVERWRITE_COOKIE_PRE = { + name: 'testOverwrite', + value: '42', + domain: 'a.com', + hostOnly: true, + path: '/', + secure: false, + httpOnly: false, + session: false, + expirationDate: 12345678900, + storeId: "0" +}; + +var OVERWRITE_COOKIE_POST = { + name: 'testOverwrite', + value: '43', + domain: 'a.com', + hostOnly: true, + path: '/', + secure: false, + httpOnly: false, + session: false, + expirationDate: 12345678900, + storeId: "0" +}; + +chrome.test.runTests([ + function testSet() { + var testCompleted = chrome.test.callbackAdded(); + var listener = function (info) { + chrome.test.assertFalse(info.removed); + chrome.test.assertEq('explicit', info.cause); + chrome.test.assertEq(SET_REMOVE_COOKIE, info.cookie); + testCompleted(); + }; -chrome.cookies.remove({url: 'http://a.com/path', name: 'test'}, function () { - removeCallbackCalled = true; -}); + chrome.cookies.onChanged.addListener(listener); + chrome.cookies.set({ + url: 'http://a.com/path', + name: 'testSetRemove', + value: '42', + expirationDate: 12345678900 + }, function () { + chrome.cookies.onChanged.removeListener(listener); + }); + }, + function testRemove() { + var testCompleted = chrome.test.callbackAdded(); + var listener = function (info) { + chrome.test.assertTrue(info.removed); + chrome.test.assertEq('explicit', info.cause); + chrome.test.assertEq(SET_REMOVE_COOKIE, info.cookie); + testCompleted(); + }; + + chrome.cookies.onChanged.addListener(listener); + chrome.cookies.remove({ + url: 'http://a.com/path', + name: 'testSetRemove' + }, function () { + chrome.cookies.onChanged.removeListener(listener); + }); + }, + function overwriteFirstSet() { + var testCompleted = chrome.test.callbackAdded(); + var listener = function (info) { + chrome.test.assertFalse(info.removed); + chrome.test.assertEq('explicit', info.cause); + chrome.test.assertEq(OVERWRITE_COOKIE_PRE, info.cookie); + testCompleted(); + }; + + chrome.cookies.onChanged.addListener(listener); + chrome.cookies.set({ + url: 'http://a.com/path', + name: 'testOverwrite', + value: '42', + expirationDate: 12345678900 + }, function () { + chrome.cookies.onChanged.removeListener(listener); + }); + }, + function overwriteSecondSet() { + var removeCompleted = chrome.test.callbackAdded(); + var setCompleted = chrome.test.callbackAdded(); + var listenerRemove = function (info) { + if (info.removed) { + chrome.test.assertEq('overwrite', info.cause); + chrome.test.assertEq(OVERWRITE_COOKIE_PRE, info.cookie); + removeCompleted(); + } + }; + var listenerSet = function (info) { + if (!info.removed) { + chrome.test.assertEq('explicit', info.cause); + chrome.test.assertEq(OVERWRITE_COOKIE_POST, info.cookie); + setCompleted(); + } + }; + chrome.cookies.onChanged.addListener(listenerRemove); + chrome.cookies.onChanged.addListener(listenerSet); + chrome.cookies.set({ + url: 'http://a.com/path', + name: 'testOverwrite', + value: '43', + expirationDate: 12345678900 + }, function () { + chrome.cookies.onChanged.removeListener(listenerRemove); + chrome.cookies.onChanged.removeListener(listenerSet); + }); + } +]); </script> |