blob: cb42e7aa05fc10e0c68957545b2ba26cceb05469 [file] [log] [blame]
Sunny Goyaleff44f32019-01-09 17:29:49 -08001package com.android.launcher3.graphics;
2
3import android.content.ContentProvider;
4import android.content.ContentValues;
Tracy Zhouc6f3b4d2020-05-23 01:24:25 -07005import android.content.pm.PackageManager;
Sunny Goyaleff44f32019-01-09 17:29:49 -08006import android.content.res.XmlResourceParser;
7import android.database.Cursor;
8import android.database.MatrixCursor;
Sunny Goyaleff44f32019-01-09 17:29:49 -08009import android.net.Uri;
Tracy Zhouc6f3b4d2020-05-23 01:24:25 -070010import android.os.Binder;
Sunny Goyaleff44f32019-01-09 17:29:49 -080011import android.os.Bundle;
Sunny Goyaleff44f32019-01-09 17:29:49 -080012import android.util.Log;
13import android.util.Xml;
14
15import com.android.launcher3.InvariantDeviceProfile;
16import com.android.launcher3.InvariantDeviceProfile.GridOption;
17import com.android.launcher3.R;
Sunny Goyaleff44f32019-01-09 17:29:49 -080018
19import org.xmlpull.v1.XmlPullParser;
20import org.xmlpull.v1.XmlPullParserException;
21
Sunny Goyaleff44f32019-01-09 17:29:49 -080022import java.io.IOException;
Sunny Goyal7d892ff2019-01-11 15:08:44 -080023import java.util.ArrayList;
24import java.util.Collections;
Sunny Goyaleff44f32019-01-09 17:29:49 -080025import java.util.List;
Sunny Goyaleff44f32019-01-09 17:29:49 -080026
27/**
28 * Exposes various launcher grid options and allows the caller to change them.
29 * APIs:
30 * /list_options: List the various available grip options, has following columns
31 * name: name of the grid
32 * rows: number of rows in the grid
33 * cols: number of columns in the grid
34 * preview_count: number of previews available for this grid option. The preview uri
35 * looks like /preview/<grid-name>/<preview index starting with 0>
36 * is_default: true if this grid is currently active
37 *
38 * /preview: Opens a file stream for the grid preview
Sunny Goyal7d892ff2019-01-11 15:08:44 -080039 *
40 * /default_grid: Call update to set the current grid, with values
41 * name: name of the grid to apply
Sunny Goyaleff44f32019-01-09 17:29:49 -080042 */
Tracy Zhou0455d142021-01-27 14:05:01 -080043public class GridCustomizationsProvider extends ContentProvider {
Sunny Goyaleff44f32019-01-09 17:29:49 -080044
Tracy Zhou0455d142021-01-27 14:05:01 -080045 private static final String TAG = "GridCustomizationsProvider";
Sunny Goyaleff44f32019-01-09 17:29:49 -080046
47 private static final String KEY_NAME = "name";
48 private static final String KEY_ROWS = "rows";
49 private static final String KEY_COLS = "cols";
50 private static final String KEY_PREVIEW_COUNT = "preview_count";
51 private static final String KEY_IS_DEFAULT = "is_default";
52
Sunny Goyal7d892ff2019-01-11 15:08:44 -080053 private static final String KEY_LIST_OPTIONS = "/list_options";
54 private static final String KEY_DEFAULT_GRID = "/default_grid";
55
Tracy Zhou85f0c3b2020-03-06 16:22:50 -080056 private static final String METHOD_GET_PREVIEW = "get_preview";
Sunny Goyaleff44f32019-01-09 17:29:49 -080057
58 @Override
59 public boolean onCreate() {
60 return true;
61 }
62
63 @Override
64 public Cursor query(Uri uri, String[] projection, String selection,
65 String[] selectionArgs, String sortOrder) {
Sunny Goyal7d892ff2019-01-11 15:08:44 -080066 if (!KEY_LIST_OPTIONS.equals(uri.getPath())) {
67 return null;
68 }
Sunny Goyaleff44f32019-01-09 17:29:49 -080069 MatrixCursor cursor = new MatrixCursor(new String[] {
70 KEY_NAME, KEY_ROWS, KEY_COLS, KEY_PREVIEW_COUNT, KEY_IS_DEFAULT});
71 InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(getContext());
Sunny Goyal7d892ff2019-01-11 15:08:44 -080072 for (GridOption gridOption : parseAllGridOptions()) {
73 cursor.newRow()
74 .add(KEY_NAME, gridOption.name)
75 .add(KEY_ROWS, gridOption.numRows)
76 .add(KEY_COLS, gridOption.numColumns)
77 .add(KEY_PREVIEW_COUNT, 1)
78 .add(KEY_IS_DEFAULT, idp.numColumns == gridOption.numColumns
79 && idp.numRows == gridOption.numRows);
80 }
81 return cursor;
82 }
83
84 private List<GridOption> parseAllGridOptions() {
85 List<GridOption> result = new ArrayList<>();
Sunny Goyaleff44f32019-01-09 17:29:49 -080086 try (XmlResourceParser parser = getContext().getResources().getXml(R.xml.device_profiles)) {
87 final int depth = parser.getDepth();
88 int type;
89 while (((type = parser.next()) != XmlPullParser.END_TAG ||
90 parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
Sunny Goyal7d892ff2019-01-11 15:08:44 -080091 if ((type == XmlPullParser.START_TAG)
92 && GridOption.TAG_NAME.equals(parser.getName())) {
93 result.add(new GridOption(getContext(), Xml.asAttributeSet(parser)));
Sunny Goyaleff44f32019-01-09 17:29:49 -080094 }
95 }
96 } catch (IOException | XmlPullParserException e) {
97 Log.e(TAG, "Error parsing device profile", e);
Sunny Goyal7d892ff2019-01-11 15:08:44 -080098 return Collections.emptyList();
Sunny Goyaleff44f32019-01-09 17:29:49 -080099 }
Sunny Goyal7d892ff2019-01-11 15:08:44 -0800100 return result;
Sunny Goyaleff44f32019-01-09 17:29:49 -0800101 }
102
103 @Override
104 public String getType(Uri uri) {
Sunny Goyaleff44f32019-01-09 17:29:49 -0800105 return "vnd.android.cursor.dir/launcher_grid";
106 }
107
108 @Override
109 public Uri insert(Uri uri, ContentValues initialValues) {
110 return null;
111 }
112
113 @Override
114 public int delete(Uri uri, String selection, String[] selectionArgs) {
115 return 0;
116 }
117
118 @Override
119 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
Sunny Goyal7d892ff2019-01-11 15:08:44 -0800120 if (!KEY_DEFAULT_GRID.equals(uri.getPath())) {
121 return 0;
122 }
123
124 String gridName = values.getAsString(KEY_NAME);
125 // Verify that this is a valid grid option
126 GridOption match = null;
127 for (GridOption option : parseAllGridOptions()) {
128 if (option.name.equals(gridName)) {
129 match = option;
130 break;
131 }
132 }
133 if (match == null) {
134 return 0;
135 }
136
137 InvariantDeviceProfile.INSTANCE.get(getContext()).setCurrentGrid(getContext(), gridName);
138 return 1;
Sunny Goyaleff44f32019-01-09 17:29:49 -0800139 }
140
141 @Override
Tracy Zhoubb353d32020-03-20 16:04:05 -0700142 public Bundle call(String method, String arg, Bundle extras) {
Tracy Zhouc6f3b4d2020-05-23 01:24:25 -0700143 if (getContext().checkPermission("android.permission.BIND_WALLPAPER",
144 Binder.getCallingPid(), Binder.getCallingUid())
145 != PackageManager.PERMISSION_GRANTED) {
146 return null;
147 }
148
Tracy Zhou85f0c3b2020-03-06 16:22:50 -0800149 if (!METHOD_GET_PREVIEW.equals(method)) {
150 return null;
151 }
152
Tracy Zhoubb353d32020-03-20 16:04:05 -0700153 return new PreviewSurfaceRenderer(getContext(), extras).render();
Tracy Zhou85f0c3b2020-03-06 16:22:50 -0800154 }
Sunny Goyaleff44f32019-01-09 17:29:49 -0800155}