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 |