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