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.server.appwidget;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.appwidget.AppWidgetProviderInfo;
22 import android.content.ComponentName;
23 import android.os.Build;
24 import android.text.TextUtils;
25 import android.util.Slog;
26 
27 import com.android.modules.utils.TypedXmlPullParser;
28 import com.android.modules.utils.TypedXmlSerializer;
29 
30 import java.io.IOException;
31 import java.util.Objects;
32 
33 /**
34  * @hide
35  */
36 public class AppWidgetXmlUtil {
37 
38     private static final String TAG = "AppWidgetXmlUtil";
39 
40     private static final String ATTR_MIN_WIDTH = "min_width";
41     private static final String ATTR_MIN_HEIGHT = "min_height";
42     private static final String ATTR_MIN_RESIZE_WIDTH = "min_resize_width";
43     private static final String ATTR_MIN_RESIZE_HEIGHT = "min_resize_height";
44     private static final String ATTR_MAX_RESIZE_WIDTH = "max_resize_width";
45     private static final String ATTR_MAX_RESIZE_HEIGHT = "max_resize_height";
46     private static final String ATTR_TARGET_CELL_WIDTH = "target_cell_width";
47     private static final String ATTR_TARGET_CELL_HEIGHT = "target_cell_height";
48     private static final String ATTR_UPDATE_PERIOD_MILLIS = "update_period_millis";
49     private static final String ATTR_INITIAL_LAYOUT = "initial_layout";
50     private static final String ATTR_INITIAL_KEYGUARD_LAYOUT = "initial_keyguard_layout";
51     private static final String ATTR_CONFIGURE = "configure";
52     private static final String ATTR_LABEL = "label";
53     private static final String ATTR_ICON = "icon";
54     private static final String ATTR_PREVIEW_IMAGE = "preview_image";
55     private static final String ATTR_PREVIEW_LAYOUT = "preview_layout";
56     private static final String ATTR_AUTO_ADVANCED_VIEW_ID = "auto_advance_view_id";
57     private static final String ATTR_RESIZE_MODE = "resize_mode";
58     private static final String ATTR_WIDGET_CATEGORY = "widget_category";
59     private static final String ATTR_WIDGET_FEATURES = "widget_features";
60     private static final String ATTR_DESCRIPTION_RES = "description_res";
61     private static final String ATTR_PROVIDER_INHERITANCE = "provider_inheritance";
62     private static final String ATTR_OS_FINGERPRINT = "os_fingerprint";
63 
64     /**
65      * @hide
66      */
writeAppWidgetProviderInfoLocked(@onNull final TypedXmlSerializer out, @NonNull final AppWidgetProviderInfo info)67     public static void writeAppWidgetProviderInfoLocked(@NonNull final TypedXmlSerializer out,
68             @NonNull final AppWidgetProviderInfo info) throws IOException {
69         Objects.requireNonNull(out);
70         Objects.requireNonNull(info);
71         out.attributeInt(null, ATTR_MIN_WIDTH, info.minWidth);
72         out.attributeInt(null, ATTR_MIN_HEIGHT, info.minHeight);
73         out.attributeInt(null, ATTR_MIN_RESIZE_WIDTH, info.minResizeWidth);
74         out.attributeInt(null, ATTR_MIN_RESIZE_HEIGHT, info.minResizeHeight);
75         out.attributeInt(null, ATTR_MAX_RESIZE_WIDTH, info.maxResizeWidth);
76         out.attributeInt(null, ATTR_MAX_RESIZE_HEIGHT, info.maxResizeHeight);
77         out.attributeInt(null, ATTR_TARGET_CELL_WIDTH, info.targetCellWidth);
78         out.attributeInt(null, ATTR_TARGET_CELL_HEIGHT, info.targetCellHeight);
79         out.attributeInt(null, ATTR_UPDATE_PERIOD_MILLIS, info.updatePeriodMillis);
80         out.attributeInt(null, ATTR_INITIAL_LAYOUT, info.initialLayout);
81         out.attributeInt(null, ATTR_INITIAL_KEYGUARD_LAYOUT, info.initialKeyguardLayout);
82         if (info.configure != null) {
83             out.attribute(null, ATTR_CONFIGURE, info.configure.flattenToShortString());
84         }
85         if (info.label != null) {
86             out.attribute(null, ATTR_LABEL, info.label);
87         } else if (AppWidgetServiceImpl.DEBUG_PROVIDER_INFO_CACHE) {
88             Slog.e(TAG, "Label is empty in " + info.provider);
89         }
90         out.attributeInt(null, ATTR_ICON, info.icon);
91         out.attributeInt(null, ATTR_PREVIEW_IMAGE, info.previewImage);
92         out.attributeInt(null, ATTR_PREVIEW_LAYOUT, info.previewLayout);
93         out.attributeInt(null, ATTR_AUTO_ADVANCED_VIEW_ID, info.autoAdvanceViewId);
94         out.attributeInt(null, ATTR_RESIZE_MODE, info.resizeMode);
95         out.attributeInt(null, ATTR_WIDGET_CATEGORY, info.widgetCategory);
96         out.attributeInt(null, ATTR_WIDGET_FEATURES, info.widgetFeatures);
97         out.attributeInt(null, ATTR_DESCRIPTION_RES, info.descriptionRes);
98         out.attributeBoolean(null, ATTR_PROVIDER_INHERITANCE, info.isExtendedFromAppWidgetProvider);
99         out.attribute(null, ATTR_OS_FINGERPRINT, Build.FINGERPRINT);
100     }
101 
102     /**
103      * @hide
104      */
105     @Nullable
readAppWidgetProviderInfoLocked( @onNull final TypedXmlPullParser parser)106     public static AppWidgetProviderInfo readAppWidgetProviderInfoLocked(
107             @NonNull final TypedXmlPullParser parser) {
108         Objects.requireNonNull(parser);
109         final String fingerprint = parser.getAttributeValue(null, ATTR_OS_FINGERPRINT);
110         if (!Build.FINGERPRINT.equals(fingerprint)) {
111             return null;
112         }
113         final AppWidgetProviderInfo info = new AppWidgetProviderInfo();
114         info.minWidth = parser.getAttributeInt(null, ATTR_MIN_WIDTH, 0);
115         info.minHeight = parser.getAttributeInt(null, ATTR_MIN_HEIGHT, 0);
116         info.minResizeWidth = parser.getAttributeInt(null, ATTR_MIN_RESIZE_WIDTH, 0);
117         info.minResizeHeight = parser.getAttributeInt(null, ATTR_MIN_RESIZE_HEIGHT, 0);
118         info.maxResizeWidth = parser.getAttributeInt(null, ATTR_MAX_RESIZE_WIDTH, 0);
119         info.maxResizeHeight = parser.getAttributeInt(null, ATTR_MAX_RESIZE_HEIGHT, 0);
120         info.targetCellWidth = parser.getAttributeInt(null, ATTR_TARGET_CELL_WIDTH, 0);
121         info.targetCellHeight = parser.getAttributeInt(null, ATTR_TARGET_CELL_HEIGHT, 0);
122         info.updatePeriodMillis = parser.getAttributeInt(null, ATTR_UPDATE_PERIOD_MILLIS, 0);
123         info.initialLayout = parser.getAttributeInt(null, ATTR_INITIAL_LAYOUT, 0);
124         info.initialKeyguardLayout = parser.getAttributeInt(
125                 null, ATTR_INITIAL_KEYGUARD_LAYOUT, 0);
126         final String configure = parser.getAttributeValue(null, ATTR_CONFIGURE);
127         if (!TextUtils.isEmpty(configure)) {
128             info.configure = ComponentName.unflattenFromString(configure);
129         }
130         info.label = parser.getAttributeValue(null, ATTR_LABEL);
131         info.icon = parser.getAttributeInt(null, ATTR_ICON, 0);
132         info.previewImage = parser.getAttributeInt(null, ATTR_PREVIEW_IMAGE, 0);
133         info.previewLayout = parser.getAttributeInt(null, ATTR_PREVIEW_LAYOUT, 0);
134         info.autoAdvanceViewId = parser.getAttributeInt(null, ATTR_AUTO_ADVANCED_VIEW_ID, 0);
135         info.resizeMode = parser.getAttributeInt(null, ATTR_RESIZE_MODE, 0);
136         info.widgetCategory = parser.getAttributeInt(null, ATTR_WIDGET_CATEGORY, 0);
137         info.widgetFeatures = parser.getAttributeInt(null, ATTR_WIDGET_FEATURES, 0);
138         info.descriptionRes = parser.getAttributeInt(null, ATTR_DESCRIPTION_RES, 0);
139         info.isExtendedFromAppWidgetProvider = parser.getAttributeBoolean(null,
140             ATTR_PROVIDER_INHERITANCE, false);
141         return info;
142     }
143 }
144