1 /* 2 * Copyright (C) 2022 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 com.android.safetycenter.internaldata; 18 19 import static android.os.Build.VERSION_CODES.TIRAMISU; 20 21 import android.util.Base64; 22 23 import androidx.annotation.RequiresApi; 24 25 import com.google.protobuf.InvalidProtocolBufferException; 26 import com.google.protobuf.MessageLite; 27 import com.google.protobuf.Parser; 28 29 /** A class to facilitate working with Safety Center IDs. */ 30 @RequiresApi(TIRAMISU) 31 public final class SafetyCenterIds { 32 33 private static final int ENCODING_FLAGS = Base64.NO_WRAP | Base64.URL_SAFE; 34 SafetyCenterIds()35 private SafetyCenterIds() {} 36 37 /** 38 * Converts a String to a {@link SafetyCenterEntryId}. 39 * 40 * <p>Throws an {@link IllegalArgumentException} if the String couldn't be converted to a {@link 41 * SafetyCenterEntryId}. 42 */ entryIdFromString(String encoded)43 public static SafetyCenterEntryId entryIdFromString(String encoded) { 44 return decodeToProto(SafetyCenterEntryId.parser(), encoded); 45 } 46 47 /** 48 * Converts a String to a {@link SafetyCenterIssueId}. 49 * 50 * <p>Throws an {@link IllegalArgumentException} if the String couldn't be converted to a {@link 51 * SafetyCenterIssueId}. 52 */ issueIdFromString(String encoded)53 public static SafetyCenterIssueId issueIdFromString(String encoded) { 54 return decodeToProto(SafetyCenterIssueId.parser(), encoded); 55 } 56 57 /** 58 * Converts a String to a {@link SafetyCenterIssueKey}. 59 * 60 * <p>Throws an {@link IllegalArgumentException} if the String couldn't be converted to a {@link 61 * SafetyCenterIssueKey}. 62 */ issueKeyFromString(String encoded)63 public static SafetyCenterIssueKey issueKeyFromString(String encoded) { 64 return decodeToProto(SafetyCenterIssueKey.parser(), encoded); 65 } 66 67 /** 68 * Converts a String to a {@link SafetyCenterIssueActionId}. 69 * 70 * <p>Throws an {@link IllegalArgumentException} if the String couldn't be converted to a {@link 71 * SafetyCenterIssueActionId}. 72 */ issueActionIdFromString(String encoded)73 public static SafetyCenterIssueActionId issueActionIdFromString(String encoded) { 74 return decodeToProto(SafetyCenterIssueActionId.parser(), encoded); 75 } 76 77 /** Encodes a Safety Center id to a String. */ encodeToString(MessageLite message)78 public static String encodeToString(MessageLite message) { 79 return Base64.encodeToString(message.toByteArray(), ENCODING_FLAGS); 80 } 81 82 /** 83 * Converts a {@link SafetyCenterIssueKey} to a readable string. 84 * 85 * <p>This is necessary as the implementation of {@link #toString()} for Java lite protos is 86 * optimized in production builds and does not return a user-readable output. 87 */ toUserFriendlyString(SafetyCenterIssueKey safetyCenterIssueKey)88 public static String toUserFriendlyString(SafetyCenterIssueKey safetyCenterIssueKey) { 89 return "SafetyCenterIssueKey{safetySourceId='" 90 + safetyCenterIssueKey.getSafetySourceId() 91 + "', safetySourceIssueId='" 92 + safetyCenterIssueKey.getSafetySourceIssueId() 93 + "', userId=" 94 + safetyCenterIssueKey.getUserId() 95 + "}"; 96 } 97 98 /** 99 * Converts a {@link SafetyCenterIssueId} to a readable string. 100 * 101 * <p>This is necessary as the implementation of {@link #toString()} for Java lite protos is 102 * optimized in production builds and does not return a user-readable output. 103 */ toUserFriendlyString(SafetyCenterIssueId safetyCenterIssueId)104 public static String toUserFriendlyString(SafetyCenterIssueId safetyCenterIssueId) { 105 return "SafetyCenterIssueId{safetyCenterIssueKey=" 106 + toUserFriendlyString(safetyCenterIssueId.getSafetyCenterIssueKey()) 107 + ", issueTypeId='" 108 + safetyCenterIssueId.getIssueTypeId() 109 + "', taskId=" 110 + safetyCenterIssueId.getTaskId() 111 + "}"; 112 } 113 114 /** 115 * Converts a {@link SafetyCenterIssueActionId} to a readable string. 116 * 117 * <p>This is necessary as the implementation of {@link #toString()} for Java lite protos is 118 * optimized in production builds and does not return a user-readable output. 119 */ toUserFriendlyString(SafetyCenterIssueActionId safetyCenterIssueActionId)120 public static String toUserFriendlyString(SafetyCenterIssueActionId safetyCenterIssueActionId) { 121 return "SafetyCenterIssueActionId{safetyCenterIssueKey=" 122 + toUserFriendlyString(safetyCenterIssueActionId.getSafetyCenterIssueKey()) 123 + ", safetySourceIssueActionId='" 124 + safetyCenterIssueActionId.getSafetySourceIssueActionId() 125 + "'}"; 126 } 127 decodeToProto(Parser<T> parser, String encoded)128 private static <T extends MessageLite> T decodeToProto(Parser<T> parser, String encoded) { 129 try { 130 return parser.parseFrom(Base64.decode(encoded, ENCODING_FLAGS)); 131 } catch (InvalidProtocolBufferException e) { 132 throw new IllegalArgumentException( 133 "Invalid ID: " 134 + encoded 135 + " couldn't be parsed with " 136 + parser.getClass().getSimpleName()); 137 } 138 } 139 } 140