| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/gdata/gdata_file_system.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_file_system.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 1537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1548 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, FilePath(), | 1548 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, FilePath(), |
| 1549 reinterpret_cast<GDataFileBase*>(NULL))); | 1549 reinterpret_cast<GDataFileBase*>(NULL))); |
| 1550 } | 1550 } |
| 1551 | 1551 |
| 1552 return; | 1552 return; |
| 1553 } | 1553 } |
| 1554 | 1554 |
| 1555 // Add the current feed to the list of collected feeds for this directory. | 1555 // Add the current feed to the list of collected feeds for this directory. |
| 1556 feed_list->Append(data.release()); | 1556 feed_list->Append(data.release()); |
| 1557 | 1557 |
| 1558 // Check if we need to collect more data to complete the directory list. | 1558 bool initial_read = false; |
| 1559 if (current_feed->GetNextFeedURL(&next_feed_url) && | 1559 { |
| 1560 !next_feed_url.is_empty()) { | 1560 base::AutoLock lock(lock_); |
| 1561 initial_read = root_->origin() == UNINITIALIZED; |
| 1562 } |
| 1563 |
| 1564 bool has_more_data = current_feed->GetNextFeedURL(&next_feed_url) && |
| 1565 !next_feed_url.is_empty(); |
| 1566 |
| 1567 // If we are completely done with feed content fetching or if this is initial |
| 1568 // batch of content feed so that we can show the initial set of files to |
| 1569 // the user as soon as the first chunk arrives, rather than waiting for all |
| 1570 // chunk to arrive. |
| 1571 if (initial_read || !has_more_data) { |
| 1572 error = UpdateDirectoryWithDocumentFeed(feed_list.get(), |
| 1573 FROM_SERVER); |
| 1574 if (error != base::PLATFORM_FILE_OK) { |
| 1575 if (!callback.is_null()) { |
| 1576 proxy->PostTask(FROM_HERE, |
| 1577 base::Bind(callback, error, FilePath(), |
| 1578 reinterpret_cast<GDataFileBase*>(NULL))); |
| 1579 } |
| 1580 |
| 1581 return; |
| 1582 } |
| 1583 |
| 1584 // If we had someone to report this too, then this retrieval was done in a |
| 1585 // context of search... so continue search. |
| 1586 if (!callback.is_null()) { |
| 1587 proxy->PostTask(FROM_HERE, |
| 1588 base::Bind(&GDataFileSystem::FindFileByPathOnCallingThread, |
| 1589 GetWeakPtrForCurrentThread(), |
| 1590 search_file_path, |
| 1591 callback)); |
| 1592 } |
| 1593 } |
| 1594 |
| 1595 if (has_more_data) { |
| 1596 // Don't report to initial callback if we were fetching the first chunk of |
| 1597 // uninitialized root feed, because we already reported. Instead, just |
| 1598 // continue with entire feed fetch in backgorund. |
| 1599 const FindFileCallback continue_callback = |
| 1600 initial_read ? FindFileCallback() : callback; |
| 1561 // Kick of the remaining part of the feeds. | 1601 // Kick of the remaining part of the feeds. |
| 1562 documents_service_->GetDocuments( | 1602 documents_service_->GetDocuments( |
| 1563 next_feed_url, | 1603 next_feed_url, |
| 1564 base::Bind(&GDataFileSystem::OnGetDocuments, | 1604 base::Bind(&GDataFileSystem::OnGetDocuments, |
| 1565 GetWeakPtrForCurrentThread(), | 1605 GetWeakPtrForCurrentThread(), |
| 1566 search_file_path, | 1606 search_file_path, |
| 1567 base::Passed(&feed_list), | 1607 base::Passed(&feed_list), |
| 1568 proxy, | 1608 proxy, |
| 1569 callback)); | 1609 continue_callback)); |
| 1570 return; | 1610 } else { |
| 1571 } | 1611 // Save completed feed in meta cache. |
| 1572 | 1612 scoped_ptr<base::Value> feed_list_value(feed_list.release()); |
| 1573 error = UpdateDirectoryWithDocumentFeed(feed_list.get(), FROM_SERVER); | 1613 SaveFeed(feed_list_value.Pass(), FilePath(kLastFeedFile)); |
| 1574 if (error != base::PLATFORM_FILE_OK) { | |
| 1575 if (!callback.is_null()) { | |
| 1576 proxy->PostTask(FROM_HERE, | |
| 1577 base::Bind(callback, error, FilePath(), | |
| 1578 reinterpret_cast<GDataFileBase*>(NULL))); | |
| 1579 } | |
| 1580 | |
| 1581 return; | |
| 1582 } | |
| 1583 | |
| 1584 scoped_ptr<base::Value> feed_list_value(feed_list.release()); | |
| 1585 SaveFeed(feed_list_value.Pass(), FilePath(kLastFeedFile)); | |
| 1586 | |
| 1587 // If we had someone to report this too, then this retrieval was done in a | |
| 1588 // context of search... so continue search. | |
| 1589 if (!callback.is_null()) { | |
| 1590 proxy->PostTask(FROM_HERE, | |
| 1591 base::Bind(&GDataFileSystem::FindFileByPathOnCallingThread, | |
| 1592 GetWeakPtrForCurrentThread(), | |
| 1593 search_file_path, | |
| 1594 callback)); | |
| 1595 } | 1614 } |
| 1596 } | 1615 } |
| 1597 | 1616 |
| 1598 void GDataFileSystem::LoadRootFeedFromCache( | 1617 void GDataFileSystem::LoadRootFeedFromCache( |
| 1599 const FilePath& search_file_path, | 1618 const FilePath& search_file_path, |
| 1600 bool load_from_server, | 1619 bool load_from_server, |
| 1601 scoped_refptr<base::MessageLoopProxy> proxy, | 1620 scoped_refptr<base::MessageLoopProxy> proxy, |
| 1602 const FindFileCallback& callback) { | 1621 const FindFileCallback& callback) { |
| 1603 BrowserThread::PostBlockingPoolTask(FROM_HERE, | 1622 BrowserThread::PostBlockingPoolTask(FROM_HERE, |
| 1604 base::Bind(&GDataFileSystem::LoadRootFeedOnIOThreadPool, | 1623 base::Bind(&GDataFileSystem::LoadRootFeedOnIOThreadPool, |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2051 GURL parent_url; | 2070 GURL parent_url; |
| 2052 const Link* parent_link = doc->GetLinkByType(Link::PARENT); | 2071 const Link* parent_link = doc->GetLinkByType(Link::PARENT); |
| 2053 if (parent_link) | 2072 if (parent_link) |
| 2054 parent_url = parent_link->href(); | 2073 parent_url = parent_link->href(); |
| 2055 | 2074 |
| 2056 UrlToFileAndParentMap::mapped_type& map_entry = | 2075 UrlToFileAndParentMap::mapped_type& map_entry = |
| 2057 file_by_url[file->self_url()]; | 2076 file_by_url[file->self_url()]; |
| 2058 // An entry with the same self link may already exist, so we need to | 2077 // An entry with the same self link may already exist, so we need to |
| 2059 // release the existing GDataFileBase instance before overwriting the | 2078 // release the existing GDataFileBase instance before overwriting the |
| 2060 // entry with another GDataFileBase instance. | 2079 // entry with another GDataFileBase instance. |
| 2080 if (map_entry.first) { |
| 2081 LOG(WARNING) << "Found duplicate file " |
| 2082 << map_entry.first->file_name(); |
| 2083 } |
| 2084 |
| 2061 delete map_entry.first; | 2085 delete map_entry.first; |
| 2062 map_entry.first = file; | 2086 map_entry.first = file; |
| 2063 map_entry.second = parent_url; | 2087 map_entry.second = parent_url; |
| 2064 } | 2088 } |
| 2065 } | 2089 } |
| 2066 | 2090 |
| 2067 if (error != base::PLATFORM_FILE_OK) { | 2091 if (error != base::PLATFORM_FILE_OK) { |
| 2068 // If the code above fails to parse a feed, any GDataFileBase instance | 2092 // If the code above fails to parse a feed, any GDataFileBase instance |
| 2069 // added to |file_by_url| is not managed by a GDataDirectory instance, | 2093 // added to |file_by_url| is not managed by a GDataDirectory instance, |
| 2070 // so we need to explicitly release them here. | 2094 // so we need to explicitly release them here. |
| 2071 for (UrlToFileAndParentMap::iterator it = file_by_url.begin(); | 2095 for (UrlToFileAndParentMap::iterator it = file_by_url.begin(); |
| 2072 it != file_by_url.end(); ++it) { | 2096 it != file_by_url.end(); ++it) { |
| 2073 delete it->second.first; | 2097 delete it->second.first; |
| 2074 } | 2098 } |
| 2075 return error; | 2099 return error; |
| 2076 } | 2100 } |
| 2077 | 2101 |
| 2102 scoped_ptr<GDataRootDirectory> orphaned_files(new GDataRootDirectory(NULL)); |
| 2078 for (UrlToFileAndParentMap::iterator it = file_by_url.begin(); | 2103 for (UrlToFileAndParentMap::iterator it = file_by_url.begin(); |
| 2079 it != file_by_url.end(); ++it) { | 2104 it != file_by_url.end(); ++it) { |
| 2080 scoped_ptr<GDataFileBase> file(it->second.first); | 2105 scoped_ptr<GDataFileBase> file(it->second.first); |
| 2081 GURL parent_url = it->second.second; | 2106 GURL parent_url = it->second.second; |
| 2082 GDataDirectory* dir = root_.get(); | 2107 GDataDirectory* dir = root_.get(); |
| 2083 if (!parent_url.is_empty()) { | 2108 if (!parent_url.is_empty()) { |
| 2084 UrlToFileAndParentMap::iterator find_iter = file_by_url.find(parent_url); | 2109 UrlToFileAndParentMap::const_iterator find_iter = |
| 2110 file_by_url.find(parent_url); |
| 2085 if (find_iter == file_by_url.end()) { | 2111 if (find_iter == file_by_url.end()) { |
| 2086 LOG(WARNING) << "Found orphaned file '" << file->file_name() | 2112 DVLOG(1) << "Found orphaned file '" << file->file_name() |
| 2087 << "' with non-existing parent folder of " | 2113 << "' with non-existing parent folder of " |
| 2088 << parent_url.spec(); | 2114 << parent_url.spec(); |
| 2115 dir = orphaned_files.get(); |
| 2089 } else { | 2116 } else { |
| 2090 dir = find_iter->second.first->AsGDataDirectory(); | 2117 dir = find_iter->second.first ? |
| 2118 find_iter->second.first->AsGDataDirectory() : NULL; |
| 2091 if (!dir) { | 2119 if (!dir) { |
| 2092 LOG(WARNING) << "Found orphaned file '" << file->file_name() | 2120 DVLOG(1) << "Found orphaned file '" << file->file_name() |
| 2093 << "' pointing to non directory parent " | 2121 << "' pointing to non directory parent " |
| 2094 << parent_url.spec(); | 2122 << parent_url.spec(); |
| 2095 dir = root_.get(); | 2123 dir = orphaned_files.get(); |
| 2096 } | 2124 } |
| 2097 } | 2125 } |
| 2098 } | 2126 } |
| 2099 DCHECK(dir); | |
| 2100 | |
| 2101 dir->AddFile(file.release()); | 2127 dir->AddFile(file.release()); |
| 2102 } | 2128 } |
| 2103 | 2129 |
| 2104 if (should_nofify) | 2130 if (should_nofify) |
| 2105 NotifyDirectoryChanged(root_->GetFilePath()); | 2131 NotifyDirectoryChanged(root_->GetFilePath()); |
| 2106 | 2132 |
| 2107 return base::PLATFORM_FILE_OK; | 2133 return base::PLATFORM_FILE_OK; |
| 2108 } | 2134 } |
| 2109 | 2135 |
| 2110 void GDataFileSystem::NotifyCacheInitialized() { | 2136 void GDataFileSystem::NotifyCacheInitialized() { |
| (...skipping 1305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3416 const bool posted = BrowserThread::PostBlockingPoolSequencedTask( | 3442 const bool posted = BrowserThread::PostBlockingPoolSequencedTask( |
| 3417 sequence_token_name, | 3443 sequence_token_name, |
| 3418 from_here, | 3444 from_here, |
| 3419 base::Bind(&GDataFileSystem::RunTaskOnIOThreadPool, | 3445 base::Bind(&GDataFileSystem::RunTaskOnIOThreadPool, |
| 3420 base::Unretained(this), | 3446 base::Unretained(this), |
| 3421 task)); | 3447 task)); |
| 3422 DCHECK(posted); | 3448 DCHECK(posted); |
| 3423 } | 3449 } |
| 3424 | 3450 |
| 3425 } // namespace gdata | 3451 } // namespace gdata |
| OLD | NEW |