@ -1,5 +1,5 @@
/ *
/ *
* Copyright © 2013 – 2015 Ricki Hirner ( bitfire web engineering ) .
* Copyright © Ricki Hirner ( bitfire web engineering ) .
* All rights reserved . This program and the accompanying materials
* All rights reserved . This program and the accompanying materials
* are made available under the terms of the GNU Public License v3 . 0
* are made available under the terms of the GNU Public License v3 . 0
* which accompanies this distribution , and is available at
* which accompanies this distribution , and is available at
@ -8,65 +8,110 @@
package com.etesync.syncadapter.syncadapter
package com.etesync.syncadapter.syncadapter
import android.accounts.*
import android.accounts.*
import android.annotation.SuppressLint
import android.app.Service
import android.app.Service
import android.content.Context
import android.content.Context
import android.content.Intent
import android.content.Intent
import android.database.DatabaseUtils
import android.os.Bundle
import android.os.Bundle
import android.os.IBinder
import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.App
import com.etesync.syncadapter.R
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.ServiceDB
import com.etesync.syncadapter.model.ServiceEntity
import com.etesync.syncadapter.resource.LocalAddressBook
import com.etesync.syncadapter.ui.setup.LoginActivity
import com.etesync.syncadapter.ui.setup.LoginActivity
import java.util.*
import java.util.logging.Level
class AccountAuthenticatorService : Service ( ) {
private var accountAuthenticator : AccountAuthenticator ? = null
/ * *
* Account authenticator for the main DAVx5 account type .
*
* Gets started when a DAVx5 account is removed , too , so it also watches for account removals
* and contains the corresponding cleanup code .
* /
class AccountAuthenticatorService : Service ( ) , OnAccountsUpdateListener {
companion object {
override fun onCreate ( ) {
@SuppressLint ( " MissingPermission " )
accountAuthenticator = AccountAuthenticator ( this )
internal fun cleanupAccounts ( context : Context ) {
}
Logger . log . info ( " Cleaning up orphaned accounts " )
override fun onBind ( intent : Intent ) : IBinder ? {
val accountNames = LinkedList < String > ( )
return if ( intent . action == android . accounts . AccountManager . ACTION _AUTHENTICATOR _INTENT ) accountAuthenticator !! . iBinder else null
val am = AccountManager . get ( context )
for ( account in am . getAccountsByType ( context . getString ( R . string . account _type ) ) ) {
accountNames . add ( account . name )
}
}
val data = ( context . applicationContext as App ) . data
private class AccountAuthenticator ( internal val context : Context ) : AbstractAccountAuthenticator ( context ) {
// delete orphaned address book accounts
for ( addrBookAccount in am . getAccountsByType ( context . getString ( R . string . account _type _address _book ) ) ) {
@Throws ( NetworkErrorException :: class )
val addressBook = LocalAddressBook ( context , addrBookAccount , null )
override fun addAccount ( response : AccountAuthenticatorResponse , accountType : String , authTokenType : String ,
try {
requiredFeatures : Array < String > , options : Bundle ) : Bundle {
if ( ! accountNames . contains ( addressBook . mainAccount . name ) )
val intent = Intent ( context , LoginActivity :: class . java )
addressBook . delete ( )
intent . putExtra ( AccountManager . KEY _ACCOUNT _AUTHENTICATOR _RESPONSE , response )
} catch ( e : ContactsStorageException ) {
val bundle = Bundle ( )
Logger . log . log ( Level . SEVERE , " Couldn't get address book main account " , e )
bundle . putParcelable ( AccountManager . KEY _INTENT , intent )
return bundle
}
}
@Throws ( NetworkErrorException :: class )
override fun confirmCredentials ( response : AccountAuthenticatorResponse , account : Account , options : Bundle ) : Bundle ? {
return null
}
}
override fun editProperties ( response : AccountAuthenticatorResponse , accountType : String ) : Bundle ? {
return null
if ( accountNames . isEmpty ( ) ) {
data . delete ( ServiceEntity :: class . java ) . get ( ) . value ( )
} else {
data . delete ( ServiceEntity :: class . java ) . where ( ServiceEntity . ACCOUNT . notIn ( accountNames ) ) . get ( ) . value ( )
}
}
}
}
private lateinit var accountManager : AccountManager
private lateinit var accountAuthenticator : AccountAuthenticator
@Throws ( NetworkErrorException :: class )
override fun getAuthToken ( response : AccountAuthenticatorResponse , account : Account , authTokenType : String , options : Bundle ) : Bundle ? {
override fun onCreate ( ) {
return null
accountManager = AccountManager . get ( this )
accountManager . addOnAccountsUpdatedListener ( this , null , true )
accountAuthenticator = AccountAuthenticator ( this )
}
}
override fun getAuthTokenLabel ( authTokenType : String ) : String ? {
override fun onDestroy ( ) {
return null
super . onDestroy ( )
accountManager . removeOnAccountsUpdatedListener ( this )
}
}
@Throws ( NetworkErrorException :: class )
override fun onBind ( intent : Intent ? ) =
override fun hasFeatures ( response : AccountAuthenticatorResponse , account : Account , features : Array < String > ) : Bundle ? {
accountAuthenticator . iBinder . takeIf { intent ?. action == android . accounts . AccountManager . ACTION _AUTHENTICATOR _INTENT }
return null
override fun onAccountsUpdated ( accounts : Array < out Account > ? ) {
cleanupAccounts ( this )
}
}
@Throws ( NetworkErrorException :: class )
override fun updateCredentials ( response : AccountAuthenticatorResponse , account : Account , authTokenType : String , options : Bundle ) : Bundle ? {
private class AccountAuthenticator (
return null
val context : Context
) : AbstractAccountAuthenticator ( context ) {
override fun addAccount ( response : AccountAuthenticatorResponse ? , accountType : String ? , authTokenType : String ? , requiredFeatures : Array < String > ? , options : Bundle ? ) : Bundle {
val intent = Intent ( context , LoginActivity :: class . java )
intent . putExtra ( AccountManager . KEY _ACCOUNT _AUTHENTICATOR _RESPONSE , response )
val bundle = Bundle ( 1 )
bundle . putParcelable ( AccountManager . KEY _INTENT , intent )
return bundle
}
}
override fun editProperties ( response : AccountAuthenticatorResponse ? , accountType : String ? ) = null
override fun getAuthTokenLabel ( p0 : String ? ) = null
override fun confirmCredentials ( p0 : AccountAuthenticatorResponse ? , p1 : Account ? , p2 : Bundle ? ) = null
override fun updateCredentials ( p0 : AccountAuthenticatorResponse ? , p1 : Account ? , p2 : String ? , p3 : Bundle ? ) = null
override fun getAuthToken ( p0 : AccountAuthenticatorResponse ? , p1 : Account ? , p2 : String ? , p3 : Bundle ? ) = null
override fun hasFeatures ( p0 : AccountAuthenticatorResponse ? , p1 : Account ? , p2 : Array < out String > ? ) = null
}
}
}
}