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.permission.safetylabel;
18 
19 import android.os.PersistableBundle;
20 import android.util.Log;
21 
22 import androidx.annotation.NonNull;
23 import androidx.annotation.Nullable;
24 import androidx.annotation.VisibleForTesting;
25 
26 import java.util.Locale;
27 
28 /** Safety Label representation containing zero or more {@link DataCategory} for data shared */
29 public class SafetyLabel {
30     private static final String TAG = "SafetyLabel";
31     @VisibleForTesting static final String KEY_SAFETY_LABEL = "safety_labels";
32     public static final String KEY_VERSION = "version";
33     private final DataLabel mDataLabel;
34 
SafetyLabel(@onNull DataLabel dataLabel)35     private SafetyLabel(@NonNull DataLabel dataLabel) {
36         this.mDataLabel = dataLabel;
37     }
38 
39     /** Returns {@link SafetyLabel} created by parsing a metadata {@link PersistableBundle} */
40     @Nullable
getSafetyLabelFromMetadata(@ullable PersistableBundle bundle)41     public static SafetyLabel getSafetyLabelFromMetadata(@Nullable PersistableBundle bundle) {
42         if (bundle == null || bundle.isEmpty()) {
43             return null;
44         }
45 
46         if (bundle.getLong(KEY_VERSION, 0L) <= 0) {
47             Log.w(TAG, String.format(
48                     Locale.US, "The top level metadata bundle have an invalid version %d",
49                     bundle.getLong(KEY_VERSION, 0L)));
50             return null;
51         }
52 
53         PersistableBundle safetyLabelBundle = bundle.getPersistableBundle(KEY_SAFETY_LABEL);
54         if (safetyLabelBundle == null) {
55             return null;
56         }
57 
58         long safetyLabelsVersion = safetyLabelBundle.getLong(KEY_VERSION, 0L);
59         if (safetyLabelsVersion <= 0) {
60             Log.w(TAG, String.format(Locale.US,
61                     "The safety labels have an invalid version %d", safetyLabelsVersion));
62             return null;
63         }
64 
65         DataLabel dataLabel = DataLabel.getDataLabel(safetyLabelBundle);
66         if (dataLabel == null) {
67             return null;
68         }
69         return new SafetyLabel(dataLabel);
70     }
71 
72     /** Returns the data label for the safety label */
73     @NonNull
getDataLabel()74     public DataLabel getDataLabel() {
75         return mDataLabel;
76     }
77 }
78