1e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song/*
2e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song * Copyright (C) 2008 The Android Open Source Project
3e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song *
4e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song * Licensed under the Apache License, Version 2.0 (the "License");
5e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song * you may not use this file except in compliance with the License.
6e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song * You may obtain a copy of the License at
7e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song *
8e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song *      http://www.apache.org/licenses/LICENSE-2.0
9e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song *
10e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song * Unless required by applicable law or agreed to in writing, software
11e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song * distributed under the License is distributed on an "AS IS" BASIS,
12e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song * See the License for the specific language governing permissions and
14e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song * limitations under the License.
15e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song */
16e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
17e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songpackage com.android.launcher3;
18e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
19e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songimport android.content.ContentValues;
20e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songimport android.content.Context;
21e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songimport android.content.Intent;
22e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songimport android.content.res.XmlResourceParser;
23e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songimport android.database.sqlite.SQLiteDatabase;
24e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songimport android.util.Log;
25e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
26e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songimport com.android.launcher3.AutoInstallsLayout.LayoutParserCallback;
27e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songimport com.android.launcher3.LauncherSettings.Favorites;
28e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songimport com.android.launcher3.backup.BackupProtos.Favorite;
29e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songimport com.android.launcher3.util.Thunk;
30e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
31e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songimport org.xmlpull.v1.XmlPullParserException;
32e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
33e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songimport java.io.IOException;
34e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
35e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song/**
36e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song * A class that parses content values corresponding to some common app types.
37e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song */
38e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Songpublic class CommonAppTypeParser implements LayoutParserCallback {
39e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    private static final String TAG = "CommonAppTypeParser";
40e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
41e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    // Including TARGET_NONE
42e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    public static final int SUPPORTED_TYPE_COUNT = 7;
43e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
44e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    private static final int RESTORE_FLAG_BIT_SHIFT = 4;
45e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
46e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
47e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    private final long mItemId;
48e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    @Thunk final int mResId;
49e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    @Thunk final Context mContext;
50e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
51e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    ContentValues parsedValues;
52e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    Intent parsedIntent;
53e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    String parsedTitle;
54e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
55e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    public CommonAppTypeParser(long itemId, int itemType, Context context) {
56e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        mItemId = itemId;
57e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        mContext = context;
58e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        mResId = getResourceForItemType(itemType);
59e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    }
60e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
61e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    @Override
62e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    public long generateNewItemId() {
63e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        return mItemId;
64e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    }
65e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
66e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    @Override
67e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    public long insertAndCheck(SQLiteDatabase db, ContentValues values) {
68e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        parsedValues = values;
69e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
70e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        // Remove unwanted values
71e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        values.put(Favorites.ICON_TYPE, (Integer) null);
72e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        values.put(Favorites.ICON_PACKAGE, (String) null);
73e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        values.put(Favorites.ICON_RESOURCE, (String) null);
74e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        values.put(Favorites.ICON, (byte[]) null);
75e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        return 1;
76e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    }
77e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
78e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    /**
79e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song     * Tries to find a suitable app to the provided app type.
80e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song     */
81e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    public boolean findDefaultApp() {
82e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        if (mResId == 0) {
83e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            return false;
84e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        }
85e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
86e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        parsedIntent = null;
87e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        parsedValues = null;
88e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        new MyLayoutParser().parseValues();
89e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        return (parsedValues != null) && (parsedIntent != null);
90e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    }
91e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
92e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    private class MyLayoutParser extends DefaultLayoutParser {
93e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
94e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        public MyLayoutParser() {
95e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            super(CommonAppTypeParser.this.mContext, null, CommonAppTypeParser.this,
96e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song                    CommonAppTypeParser.this.mContext.getResources(), mResId, TAG_RESOLVE, 0);
97e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        }
98e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
99e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        @Override
100e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        protected long addShortcut(String title, Intent intent, int type) {
101e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            if (type == Favorites.ITEM_TYPE_APPLICATION) {
102e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song                parsedIntent = intent;
103e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song                parsedTitle = title;
104e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            }
105e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            return super.addShortcut(title, intent, type);
106e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        }
107e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
108e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        public void parseValues() {
109e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            XmlResourceParser parser = mSourceRes.getXml(mLayoutId);
110e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            try {
111e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song                beginDocument(parser, mRootTag);
112e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song                new ResolveParser().parseAndAdd(parser);
113e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            } catch (IOException | XmlPullParserException e) {
114e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song                Log.e(TAG, "Unable to parse default app info", e);
115e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            }
116e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            parser.close();
117e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        }
118e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    }
119e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
120e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    public static int getResourceForItemType(int type) {
121e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        switch (type) {
122e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            case Favorite.TARGET_PHONE:
123e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song                return R.xml.app_target_phone;
124e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
125e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            case Favorite.TARGET_MESSENGER:
126e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song                return R.xml.app_target_messenger;
127e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
128e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            case Favorite.TARGET_EMAIL:
129e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song                return R.xml.app_target_email;
130e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
131e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            case Favorite.TARGET_BROWSER:
132e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song                return R.xml.app_target_browser;
133e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
134e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            case Favorite.TARGET_GALLERY:
135e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song                return R.xml.app_target_gallery;
136e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
137e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            case Favorite.TARGET_CAMERA:
138e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song                return R.xml.app_target_camera;
139e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
140e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song            default:
141e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song                return 0;
142e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        }
143e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    }
144e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
145e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    public static int encodeItemTypeToFlag(int itemType) {
146e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        return itemType << RESTORE_FLAG_BIT_SHIFT;
147e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    }
148e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
149e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    public static int decodeItemTypeFromFlag(int flag) {
150e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song        return (flag & ShortcutInfo.FLAG_RESTORED_APP_TYPE) >> RESTORE_FLAG_BIT_SHIFT;
151e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song    }
152e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song
153e612775922ec9f8cc4e5cb976bc62b3312a3de0eHyunyoung Song}
154