1 /* 2 * Copyright 2025 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.appfunctions.schema.notes.translators 18 19 import androidx.annotation.RequiresApi 20 import androidx.appfunctions.AppFunctionData 21 import androidx.appfunctions.AppFunctionSerializable 22 import androidx.appfunctions.ExecuteAppFunctionResponse.Success.Companion.PROPERTY_RETURN_VALUE 23 import androidx.appfunctions.internal.Translator 24 import androidx.appfunctions.schema.notes.FindNotesAppFunction 25 import androidx.appfunctions.schema.notes.translators.NoteTranslator.downgradeNote 26 import androidx.appfunctions.schema.notes.translators.NoteTranslator.upgradeNote 27 import java.time.LocalDateTime 28 import java.time.ZoneId 29 30 @RequiresApi(33) 31 internal class FindNotesTranslator : Translator { upgradeRequestnull32 override fun upgradeRequest(request: AppFunctionData): AppFunctionData { 33 val legacyFindNoteParams = checkNotNull(request.getAppFunctionData("findNotesParams")) 34 35 val parameters = 36 FindNotesAppFunctionParams( 37 query = legacyFindNoteParams.getStringOrNull("query"), 38 modifiedAfter = 39 legacyFindNoteParams.getAppFunctionData("startDate")?.toLocalDateTime(), 40 modifiedBefore = 41 legacyFindNoteParams.getAppFunctionData("endDate")?.toLocalDateTime() 42 ) 43 44 return AppFunctionData.Builder(qualifiedName = "") 45 .setAppFunctionData( 46 "parameters", 47 AppFunctionData.serialize(parameters, FindNotesAppFunctionParams::class.java) 48 ) 49 .build() 50 } 51 upgradeResponsenull52 override fun upgradeResponse(response: AppFunctionData): AppFunctionData { 53 val legacyFindNotesResponse = 54 checkNotNull(response.getAppFunctionDataList(PROPERTY_RETURN_VALUE)) 55 56 val notes = legacyFindNotesResponse.map { it.upgradeNote() } 57 58 return AppFunctionData.Builder(qualifiedName = "") 59 .setAppFunctionData( 60 PROPERTY_RETURN_VALUE, 61 AppFunctionData.serialize( 62 FindNotesAppFunctionResponse(notes), 63 FindNotesAppFunctionResponse::class.java 64 ) 65 ) 66 .build() 67 } 68 downgradeRequestnull69 override fun downgradeRequest(request: AppFunctionData): AppFunctionData { 70 val parametersData = checkNotNull(request.getAppFunctionData("parameters")) 71 val findNotesAppFunctionParams = 72 parametersData.deserialize(FindNotesAppFunctionParams::class.java) 73 val downgradedRequestData = 74 AppFunctionData.Builder(qualifiedName = "") 75 .apply { 76 if (findNotesAppFunctionParams.query != null) { 77 setString("query", findNotesAppFunctionParams.query) 78 } 79 if (findNotesAppFunctionParams.modifiedAfter != null) { 80 setAppFunctionData( 81 "startDate", 82 findNotesAppFunctionParams.modifiedAfter.toLegacyAppFunctionData() 83 ) 84 } 85 if (findNotesAppFunctionParams.modifiedBefore != null) { 86 setAppFunctionData( 87 "endDate", 88 findNotesAppFunctionParams.modifiedBefore.toLegacyAppFunctionData() 89 ) 90 } 91 92 setInt("maxCount", Int.MAX_VALUE) 93 } 94 .build() 95 return AppFunctionData.Builder(qualifiedName = "") 96 .setAppFunctionData("findNotesParams", downgradedRequestData) 97 .build() 98 } 99 downgradeResponsenull100 override fun downgradeResponse(response: AppFunctionData): AppFunctionData { 101 val responseData = checkNotNull(response.getAppFunctionData(PROPERTY_RETURN_VALUE)) 102 val findNotesAppFunctionResponse = 103 responseData.deserialize(FindNotesAppFunctionResponse::class.java) 104 return AppFunctionData.Builder(qualifiedName = "") 105 .setAppFunctionDataList( 106 PROPERTY_RETURN_VALUE, 107 findNotesAppFunctionResponse.notes.map { it.downgradeNote() } 108 ) 109 .build() 110 } 111 112 companion object { toLocalDateTimenull113 private fun AppFunctionData.toLocalDateTime(): LocalDateTime { 114 val date = checkNotNull(getAppFunctionData("date")) 115 val timeOfDay = checkNotNull(getAppFunctionData("timeOfDay")) 116 return LocalDateTime.of( 117 /* year= */ date.getInt("year"), 118 /* month= */ date.getInt("month"), 119 /* dayOfMonth= */ date.getInt("day"), 120 /* hour= */ timeOfDay.getInt("hours"), 121 /* minute= */ timeOfDay.getInt("minutes"), 122 /* second= */ timeOfDay.getInt("seconds"), 123 /* nanoOfSecond= */ timeOfDay.getInt("nanos") 124 ) 125 } 126 LocalDateTimenull127 private fun LocalDateTime.toLegacyAppFunctionData() = 128 AppFunctionData.Builder(qualifiedName = "") 129 // Use default time zone on device since in new schema we don't support specifying 130 // time zone. 131 .setString("timeZone", ZoneId.systemDefault().toString()) 132 .setAppFunctionData( 133 "date", 134 AppFunctionData.Builder(qualifiedName = "") 135 .setInt("year", year) 136 .setInt("month", monthValue) 137 .setInt("day", dayOfMonth) 138 .build() 139 ) 140 .setAppFunctionData( 141 "timeOfDay", 142 AppFunctionData.Builder(qualifiedName = "") 143 .setInt("hours", hour) 144 .setInt("minutes", minute) 145 .setInt("seconds", second) 146 .setInt("nanos", nano) 147 .build() 148 ) 149 .build() 150 } 151 } 152 153 @AppFunctionSerializable 154 internal data class FindNotesAppFunctionParams( 155 override val query: String? = null, 156 override val modifiedAfter: LocalDateTime? = null, 157 override val modifiedBefore: LocalDateTime? = null 158 ) : FindNotesAppFunction.Parameters 159 160 @AppFunctionSerializable 161 internal data class FindNotesAppFunctionResponse( 162 override val notes: List<AppFunctionNoteImpl> = emptyList() 163 ) : FindNotesAppFunction.Response 164