@@ -12,106 +12,159 @@ import { SettingsInitializer } from 'vs/platform/userDataSync/common/settingsSyn
1212import { SnippetsInitializer } from 'vs/platform/userDataSync/common/snippetsSync' ;
1313import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService' ;
1414import { IFileService } from 'vs/platform/files/common/files' ;
15- import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation' ;
15+ import { createDecorator , IInstantiationService } from 'vs/platform/instantiation/common/instantiation' ;
1616import { ILogService } from 'vs/platform/log/common/log' ;
1717import { UserDataSyncStoreClient } from 'vs/platform/userDataSync/common/userDataSyncStoreService' ;
1818import { IProductService } from 'vs/platform/product/common/productService' ;
1919import { IRequestService } from 'vs/platform/request/common/request' ;
20- import { CONFIGURATION_SYNC_STORE_KEY } from 'vs/platform/userDataSync/common/userDataSync' ;
20+ import { CONFIGURATION_SYNC_STORE_KEY , IUserDataSyncStoreClient , SyncResource } from 'vs/platform/userDataSync/common/userDataSync' ;
2121import { URI } from 'vs/base/common/uri' ;
2222import { getAuthenticationSession } from 'vs/workbench/services/authentication/browser/authenticationService' ;
23+ import { getSyncAreaLabel } from 'vs/workbench/services/userDataSync/common/userDataSync' ;
24+ import { IWorkbenchContribution , IWorkbenchContributionsRegistry , Extensions } from 'vs/workbench/common/contributions' ;
25+ import { Registry } from 'vs/platform/registry/common/platform' ;
26+ import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle' ;
27+ import { isWeb } from 'vs/base/common/platform' ;
2328
24- export function initializeUserData (
25- environmentService : IWorkbenchEnvironmentService ,
26- fileService : IFileService ,
27- storageService : IStorageService ,
28- productService : IProductService ,
29- requestService : IRequestService ,
30- logService : ILogService ,
31- ) : Promise < void > {
32- const initializers : AbstractInitializer [ ] = [
33- new SettingsInitializer ( fileService , environmentService , logService ) ,
34- new KeybindingsInitializer ( fileService , environmentService , logService ) ,
35- new SnippetsInitializer ( fileService , environmentService , logService ) ,
36- new GlobalStateInitializer ( storageService , fileService , environmentService , logService ) ,
37- ] ;
38- return initialize ( initializers , 'user data' , environmentService , fileService , storageService , productService , requestService , logService ) ;
39- }
29+ export const IUserDataInitializationService = createDecorator < IUserDataInitializationService > ( 'IUserDataInitializationService' ) ;
30+ export interface IUserDataInitializationService {
31+ _serviceBrand : any ;
4032
41- export function initializeExtensions ( instantiationService : IInstantiationService ) : Promise < void > {
42- return instantiationService . invokeFunction ( accessor => {
43- return initialize ( [ instantiationService . createInstance ( ExtensionsInitializer ) ] , 'extensions' ,
44- accessor . get ( IWorkbenchEnvironmentService ) ,
45- accessor . get ( IFileService ) ,
46- accessor . get ( IStorageService ) ,
47- accessor . get ( IProductService ) ,
48- accessor . get ( IRequestService ) ,
49- accessor . get ( ILogService ) ) ;
50- } ) ;
33+ initializeRequiredResources ( ) : Promise < void > ;
34+ initializeOtherResources ( ) : Promise < void > ;
35+ initializeExtensions ( instantiationService : IInstantiationService ) : Promise < void > ;
5136}
5237
53- async function initialize (
54- initializers : AbstractInitializer [ ] ,
55- userDataLabel : string ,
56- environmentService : IWorkbenchEnvironmentService ,
57- fileService : IFileService ,
58- storageService : IStorageService ,
59- productService : IProductService ,
60- requestService : IRequestService ,
61- logService : ILogService ,
62- ) : Promise < void > {
63-
64- if ( ! environmentService . options ?. enableSyncByDefault ) {
65- logService . trace ( `Skipping initializing ${ userDataLabel } as sync is not enabled by default` ) ;
66- return ;
67- }
38+ export class UserDataInitializationService implements IUserDataInitializationService {
6839
69- if ( ! storageService . isNew ( StorageScope . GLOBAL ) ) {
70- logService . trace ( `Skipping initializing ${ userDataLabel } as application was opened before` ) ;
71- return ;
72- }
40+ _serviceBrand : any ;
7341
74- if ( ! storageService . isNew ( StorageScope . WORKSPACE ) ) {
75- logService . trace ( `Skipping initializing ${ userDataLabel } as workspace was opened before` ) ;
76- return ;
77- }
42+ private readonly initialized : SyncResource [ ] = [ ] ;
43+
44+ constructor (
45+ @IWorkbenchEnvironmentService private readonly environmentService : IWorkbenchEnvironmentService ,
46+ @IFileService private readonly fileService : IFileService ,
47+ @IStorageService private readonly storageService : IStorageService ,
48+ @IProductService private readonly productService : IProductService ,
49+ @IRequestService private readonly requestService : IRequestService ,
50+ @ILogService private readonly logService : ILogService
51+ ) { }
52+
53+ private _userDataSyncStoreClientPromise : Promise < IUserDataSyncStoreClient | undefined > | undefined ;
54+ private createUserDataSyncStoreClient ( ) : Promise < IUserDataSyncStoreClient | undefined > {
55+ if ( ! this . _userDataSyncStoreClientPromise ) {
56+ this . _userDataSyncStoreClientPromise = ( async ( ) : Promise < IUserDataSyncStoreClient | undefined > => {
57+ if ( ! isWeb ) {
58+ this . logService . trace ( `Skipping initializing user data in desktop` ) ;
59+ return ;
60+ }
61+
62+ if ( ! this . environmentService . options ?. enableSyncByDefault ) {
63+ this . logService . trace ( `Skipping initializing user data as sync is not enabled by default` ) ;
64+ return ;
65+ }
7866
79- const userDataSyncStore = productService [ CONFIGURATION_SYNC_STORE_KEY ] ;
80- if ( ! userDataSyncStore ) {
81- logService . trace ( `Skipping initializing ${ userDataLabel } as sync service is not provided` ) ;
82- return ;
67+ if ( ! this . storageService . isNew ( StorageScope . GLOBAL ) ) {
68+ this . logService . trace ( `Skipping initializing user data as application was opened before` ) ;
69+ return ;
70+ }
71+
72+ if ( ! this . storageService . isNew ( StorageScope . WORKSPACE ) ) {
73+ this . logService . trace ( `Skipping initializing user data as workspace was opened before` ) ;
74+ return ;
75+ }
76+
77+ const userDataSyncStore = this . productService [ CONFIGURATION_SYNC_STORE_KEY ] ;
78+ if ( ! userDataSyncStore ) {
79+ this . logService . trace ( `Skipping initializing user data as sync service is not provided` ) ;
80+ return ;
81+ }
82+
83+ if ( ! this . environmentService . options ?. credentialsProvider ) {
84+ this . logService . trace ( `Skipping initializing user data as credentials provider is not provided` ) ;
85+ return ;
86+ }
87+
88+ let authenticationSession ;
89+ try {
90+ authenticationSession = await getAuthenticationSession ( this . environmentService . options . credentialsProvider , this . productService ) ;
91+ } catch ( error ) {
92+ this . logService . error ( error ) ;
93+ }
94+ if ( ! authenticationSession ) {
95+ this . logService . trace ( `Skipping initializing user data as authentication session is not set` ) ;
96+ return ;
97+ }
98+
99+ const userDataSyncStoreClient = new UserDataSyncStoreClient ( URI . parse ( userDataSyncStore . url ) , this . productService , this . requestService , this . logService , this . environmentService , this . fileService , this . storageService ) ;
100+ userDataSyncStoreClient . setAuthToken ( authenticationSession . accessToken , authenticationSession . providerId ) ;
101+ return userDataSyncStoreClient ;
102+ } ) ( ) ;
103+ }
104+
105+ return this . _userDataSyncStoreClientPromise ;
83106 }
84107
85- if ( ! environmentService . options ?. credentialsProvider ) {
86- return ;
108+ async initializeRequiredResources ( ) : Promise < void > {
109+ return this . initialize ( [ SyncResource . Settings , SyncResource . GlobalState ] ) ;
87110 }
88111
89- let authenticationSession ;
90- try {
91- authenticationSession = await getAuthenticationSession ( environmentService . options . credentialsProvider , productService ) ;
92- } catch ( error ) {
93- logService . error ( error ) ;
112+ async initializeOtherResources ( ) : Promise < void > {
113+ return this . initialize ( [ SyncResource . Keybindings , SyncResource . Snippets ] ) ;
94114 }
95- if ( ! authenticationSession ) {
96- logService . trace ( `Skipping initializing ${ userDataLabel } as authentication session is not set` ) ;
97- return ;
115+
116+ async initializeExtensions ( instantiationService : IInstantiationService ) : Promise < void > {
117+ return this . initialize ( [ SyncResource . Extensions ] , instantiationService ) ;
98118 }
99119
100- const userDataSyncStoreClient = new UserDataSyncStoreClient ( URI . parse ( userDataSyncStore . url ) , productService , requestService , logService , environmentService , fileService , storageService ) ;
101- try {
102- userDataSyncStoreClient . setAuthToken ( authenticationSession . accessToken , authenticationSession . providerId ) ;
103- logService . info ( `Started initializing ${ userDataLabel } ` ) ;
104- for ( const initializer of initializers ) {
120+ private async initialize ( syncResources : SyncResource [ ] , instantiationService ?: IInstantiationService ) : Promise < void > {
121+ const userDataSyncStoreClient = await this . createUserDataSyncStoreClient ( ) ;
122+ if ( ! userDataSyncStoreClient ) {
123+ return ;
124+ }
125+
126+ await Promise . all ( syncResources . map ( async syncResource => {
105127 try {
106- const userData = await userDataSyncStoreClient . read ( initializer . resource , null ) ;
128+ if ( this . initialized . includes ( syncResource ) ) {
129+ this . logService . info ( `${ getSyncAreaLabel ( syncResource ) } initialized already.` ) ;
130+ return ;
131+ }
132+ this . initialized . push ( syncResource ) ;
133+ this . logService . trace ( `Initializing ${ getSyncAreaLabel ( syncResource ) } ` ) ;
134+ const initializer = this . createSyncResourceInitializer ( syncResource , instantiationService ) ;
135+ const userData = await userDataSyncStoreClient . read ( syncResource , null ) ;
107136 await initializer . initialize ( userData ) ;
137+ this . logService . info ( `Initialized ${ getSyncAreaLabel ( syncResource ) } ` ) ;
108138 } catch ( error ) {
109- logService . info ( `Error while initializing ${ initializer . resource } ` ) ;
110- logService . error ( error ) ;
139+ this . logService . info ( `Error while initializing ${ getSyncAreaLabel ( syncResource ) } ` ) ;
140+ this . logService . error ( error ) ;
111141 }
142+ } ) ) ;
143+ }
144+
145+ private createSyncResourceInitializer ( syncResource : SyncResource , instantiationService ?: IInstantiationService ) : AbstractInitializer {
146+ switch ( syncResource ) {
147+ case SyncResource . Settings : return new SettingsInitializer ( this . fileService , this . environmentService , this . logService ) ;
148+ case SyncResource . Keybindings : return new KeybindingsInitializer ( this . fileService , this . environmentService , this . logService ) ;
149+ case SyncResource . Snippets : return new SnippetsInitializer ( this . fileService , this . environmentService , this . logService ) ;
150+ case SyncResource . GlobalState : return new GlobalStateInitializer ( this . storageService , this . fileService , this . environmentService , this . logService ) ;
151+ case SyncResource . Extensions :
152+ if ( ! instantiationService ) {
153+ throw new Error ( 'Instantiation Service is required to initialize extension' ) ;
154+ }
155+ return instantiationService . createInstance ( ExtensionsInitializer ) ;
112156 }
113- logService . info ( `Initializing ${ userDataLabel } completed` ) ;
114- } finally {
115- userDataSyncStoreClient . dispose ( ) ;
116157 }
158+
159+ }
160+
161+ class InitializeOtherResourcesContribution implements IWorkbenchContribution {
162+ constructor ( @IUserDataInitializationService userDataInitializeService : IUserDataInitializationService ) {
163+ userDataInitializeService . initializeOtherResources ( ) ;
164+ }
165+ }
166+
167+ if ( isWeb ) {
168+ const workbenchRegistry = Registry . as < IWorkbenchContributionsRegistry > ( Extensions . Workbench ) ;
169+ workbenchRegistry . registerWorkbenchContribution ( InitializeOtherResourcesContribution , LifecyclePhase . Eventually ) ;
117170}
0 commit comments