Drive KitでHUAWEI Driveに接続する方法

# HUAWEI Driveに接続する手順
1. HUAWEI IDでHUAWEIアカウントにログインする
2. DriveCredentialオブジェクトを生成する
3. Driveオブジェクトを生成する

# HUAWEIアカウントへのログイン
Account KitでHUAWEIアカウントにログインする場合、2つの方法があります。

1. Authorization Codeによるログイン
2. ID Tokenによるログイン

Authorization Codeを使う場合、Union Idは取得できますが、Access Tokenは取得できません。
ID Tokenを使えば、Union IdとAccess Tokenを取得できます。,

また、ログイン時にHUAWEI Driveのスコープを指定する必要があります。

```kotlin
private var accountAuthService: AccountAuthService? = null

fun signInInit(context: Context) {
    // HUAWEI Driveのアクセス権限
    val scopeList: List<Scope> = listOf(
        Scope(DriveScopes.SCOPE_DRIVE_APPDATA),
        Scope(DriveScopes.SCOPE_DRIVE_FILE)
    )

    val param = AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
        .setAccessToken()
        .setIdToken()
        .setScopeList(scopeList)
        .createParams()
    accountAuthService = AccountAuthManager.getService(context, param)
}

fun signInCallback(result: ActivityResult) {
    val authHuaweiIdTask = HuaweiIdAuthManager.parseAuthResultFromIntent(result.data)
    if (authHuaweiIdTask.isSuccessful) {
        with (authHuaweiIdTask.result) {
            // Union Id = this.unionId
            // Access Token = this.accessToken
    }
}
```

# HUAWEI Driveのアクセス権限
HUAWEIアカウントにログイン時にHUAWEI Driveのスコープを渡さなければなりません。次のスコープを渡せます。

|スコープ名|詳細|
|:---|:---|
|SCOPE_DRIVE_FILE|アプリが作ったファイルとフォルダのアクセス権限|
|SCOPE_DRIVE_APPDATA|アプリデータのアクセス権限|
|SCOPE_DRIVE|アプリデータ以外のすべてのアクセス権限|
|SCOPE_DRIVE_READONLY|ファイルの読み込み権限のみ|
|SCOPE_DRIVE_METADATA|ファイルのメタデータの読み込みと書き込み権限|
|SCOPE_DRIVE_METADATA_READONLY|ファイルのメタデータの読み込み権限|

https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides/dev-guide-account-0000001050048888#section179491049132715

# HUAWEI Driveへの接続
DriveCredentialオブジェクトを生成し、Driveオブジェクトを生成するだけで接続できます。

```kotlin
private var credential: DriveCredential? = null
private var drive: Drive? = null

if (unionID.isNotBlank() && accessToken.isNotBlank()) {
    credential = DriveCredential.Builder(unionID, accessMethod)
                    .build()
                    .setAccessToken(accessToken)
    credential?.let {
        drive = Drive.Builder(it, context).build()
    }
}
```

# AccessMethodについて
DriveCredentialオブジェクトを生成するときにDriveCredential.AccessMethodを渡さなければなりません。
そのrefreshToken()内では更新されたアクセストークンを返す必要があります。

```kotlin
object : DriveCredential.AccessMethod {
    override fun refreshToken(): String {
        // ロック
        reentrantLock.lock()
        // サイレントサインインし、最新のアクセストークンを取得し、どこかに保存する
        slientSignIn()
        // アンロック
        reentrantLock.unlock()
        // 保存されたアクセストークンを返す
        return {保存されたアクセストークン}
    }
}
```

```kotlin
fun slientSignIn() {
    accountAuthService?.let {
        val task = it.silentSignIn()
        task.addOnSuccessListener(OnSuccessListener<AuthAccount> { authAccount ->
            // アクセストークン = authAccount.accessToken
            // アクセストークンをどこかに保存する
        })
        task.addOnFailureListener(OnFailureListener { e ->
            // エラー
        })
    }
}

```

# GitHub
HMS Drive Kit Demo : https://github.com/Rei2020GitHub/MyPublicProject/tree/master/DriveKitDemo

# 参考
* HMS：[https://developer.huawei.com/consumer/jp/](https://developer.huawei.com/consumer/jp/)
* HMS Drive Kitの紹介：https://developer.huawei.com/consumer/jp/hms/huawei-drivekit
* HMS Drive Kitのドキュメント：https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides/introduction-0000001050039630
* Huawei Developers：https://forums.developer.huawei.com/forumPortal/en/home
* Facebook Huawei Developersグループ：https://www.facebook.com/Huaweidevs/