首先,chromium除了默認主題外,其它都是以chrome拓展的方式安裝的,所以對於一個新的主題,需要定一個主題id,這個主題id可以先自己定一個,只要長度一致就可以了,但是主題id會有字母範圍的限制,所以可以找一個現成的id,然後直接交換幾個字母的位置就可以,後繼這個id並不會真正用到。
src\chrome\browser\themes\theme_service.cc
const char* ThemeService::kDefaultThemeID = "";
const char* ThemeService::kNewDefaultThemeID = "ndoippcjlipfddffdcimakhebaemnmgn";
在theme_service_factory.cc中設置默認註冊的主題id爲新的主題id。
src\chrome\browser\themes\theme_service_factory.cc
registry->RegisterStringPref(
prefs::kCurrentThemeID,
ThemeService::kNewDefaultThemeID,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
在chrome啓動後,會調用ThemeService::Init函數,進而進入LoadThemePrefs函數,但是進入LoadThemePrefs後,這裏是不載入主題的,因爲當前current_id等於kNewDefaultThemeID,kCurrentThemePackFilename爲空。ThemeService會監聽NOTIFICATION_EXTENSIONS_READY信號,當extension系統啓動完成後,調用ThemeService的OnExtensionServiceReady函數,接下來就可以通過extension系統加載主題。在OnExtensionServiceReady函數中,ready_當前的值爲false,因爲沒有載入任何主題。調用MigrateTheme函數,將函數修改爲
void ThemeService::MigrateTheme() {
// TODO(erg): We need to pop up a dialog informing the user that their
// theme is being migrated.
ExtensionService* service =
extensions::ExtensionSystem::Get(profile_)->extension_service();
const Extension* extension = service ?
service->GetExtensionById(GetThemeID(), false) : NULL;
if (extension) {
DLOG(ERROR) << "Migrating theme";
BuildFromExtension(extension);
content::RecordAction(UserMetricsAction("Themes.Migrated"));
} else {
if (GetThemeID() == kNewDefaultThemeID) {
base::FilePath dir_exe;
PathService::Get(base::DIR_EXE, &dir_exe);
base::FilePath new_theme_dir(dir_exe.value() + FILE_PATH_LITERAL("/new_theme"));
extensions::UnpackedInstaller::Create(service)->Load(new_theme_dir);
} else {
DLOG(ERROR) << "Theme is mysteriously gone.";
ClearAllThemeData();
content::RecordAction(UserMetricsAction("Themes.Gone"));
}
}
}
由於初始的主題id是kNewDefaultThemeID,會需要從給定文件夾new_theme_dir載入主題拓展。MigrateTheme運行完畢調用NotifyThemeChanged,主題加載完成。在重置主題時,會調用ClearAllThemeData函數,該函數重新設置主題id,並重新載入主題。
void ThemeService::ClearAllThemeData() {
if (!ready_)
return;
SwapThemeSupplier(NULL);
FreePlatformCaches();
profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename);
SaveThemeID(kNewDefaultThemeID);
base::MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(&ThemeService::RemoveUnusedThemes,
weak_ptr_factory_.GetWeakPtr(),
true));
MigrateTheme();
}