Preparing my gsoc application (I've decided to go for GnomeKeyring
password storage), I've read the code and debugged a bit to see how
the passwords are currently stored. In general, on startup the
following takes place:
AccountManager loads the accounts on start-up in a separate thread.
It's doLoadStoredAccounts() method is called for all supported
ProtocolProviderFactory implementations, and this method (besides
other things) decodes the stored password and puts it in a map along
with other properties; the map is then passed into the
ProtocolProviderFactory.loadAccount. This is done for all accounts for
the given protocol. Now, inside ProtocolProviderFactory.loadAccount, a
protocol specific AccountID is created from the passed-in properties
map. After that, things get interesting: in the same method
ServiceRegistration object is created with the call
bundleContext.registerService(...). This triggers inside a new thread
a call chain from ProtocolProviderFactory*Impl.register() (which has
our created AccountID with the password inside) to
ProtocolProviderFactory.loadPassword(bundleContext, accountID) which
does the same thing as doLoadStoredAccounts() - loads and decodes the
password!
So why do double work? Is it required somehow further in the
execution, or is it just old code? Maybe you have plans how to
refactor it, there is a TODO there: "Delegate the implementation to
{@link AccountManager} because it knows the format in which the
password (among the other account properties) was saved."

That's actually a good example of GSoC related questions that could
still go to dev since they are mostly about the code and not so much
about the program

(more inline)

На 29.03.10 15:15, Dmitri Melnikov написа:

Hello everyone,

Preparing my gsoc application (I've decided to go for GnomeKeyring
password storage), I've read the code and debugged a bit to see how
the passwords are currently stored. In general, on startup the
following takes place:
AccountManager loads the accounts on start-up in a separate thread.
It's doLoadStoredAccounts() method is called for all supported
ProtocolProviderFactory implementations, and this method (besides
other things) decodes the stored password and puts it in a map along
with other properties; the map is then passed into the
ProtocolProviderFactory.loadAccount. This is done for all accounts for
the given protocol. Now, inside ProtocolProviderFactory.loadAccount, a
protocol specific AccountID is created from the passed-in properties
map. After that, things get interesting: in the same method
ServiceRegistration object is created with the call
bundleContext.registerService(...). This triggers inside a new thread
a call chain from ProtocolProviderFactory*Impl.register() (which has
our created AccountID with the password inside) to
ProtocolProviderFactory.loadPassword(bundleContext, accountID) which
does the same thing as doLoadStoredAccounts() - loads and decodes the
password!
So why do double work? Is it required somehow further in the
execution, or is it just old code? Maybe you have plans how to
refactor it, there is a TODO there: "Delegate the implementation to
{@link AccountManager} because it knows the format in which the
password (among the other account properties) was saved."

It is indeed a bit redundant. I guess we don't really need the password
to be stored in the account properties and we probably only did it when
refactoring for backward compatibility with older bundles. In any case
it seems like we should only retrieve it through load password when we
actually need it.

I don't have the time to check this in detail right now though, so you
should take my words with a grain of salt. You may want to experiment a
bit with the code and try to confirm it. Either way you should
definitely include the above and any results from future experimentation
in your application.