diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2019-03-22 14:13:36 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2019-04-10 12:06:17 -0700 |
commit | c0f03d96656a3c70a26d3ec97e9e782fbdbe64b9 (patch) | |
tree | 8696c1cb8b375fc1efa50e8ae4fed2a5c51d1010 /src | |
parent | e09e1f2253a9f20f1c91532956053a11b43ad355 (diff) | |
download | android_packages_apps_Trebuchet-c0f03d96656a3c70a26d3ec97e9e782fbdbe64b9.tar.gz android_packages_apps_Trebuchet-c0f03d96656a3c70a26d3ec97e9e782fbdbe64b9.tar.bz2 android_packages_apps_Trebuchet-c0f03d96656a3c70a26d3ec97e9e782fbdbe64b9.zip |
Adding support for loading the default layout from a content provider
The autority of the provider should be set in secure settings:
launcher3.layout.provider
Bug: 127987071
Change-Id: Iccf2960aa6c0a5a8ff9621b13d8963d9daecb993
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/launcher3/AutoInstallsLayout.java | 30 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherProvider.java | 56 |
2 files changed, 55 insertions, 31 deletions
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java index 62bc53a81..0d9bd3195 100644 --- a/src/com/android/launcher3/AutoInstallsLayout.java +++ b/src/com/android/launcher3/AutoInstallsLayout.java @@ -50,6 +50,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.Locale; +import java.util.function.Supplier; /** * Layout parsing code for auto installs layout @@ -76,12 +77,8 @@ public class AutoInstallsLayout { if (customizationApkInfo == null) { return null; } - return get(context, customizationApkInfo.first, customizationApkInfo.second, - appWidgetHost, callback); - } - - static AutoInstallsLayout get(Context context, String pkg, Resources targetRes, - AppWidgetHost appWidgetHost, LayoutParserCallback callback) { + String pkg = customizationApkInfo.first; + Resources targetRes = customizationApkInfo.second; InvariantDeviceProfile grid = LauncherAppState.getIDP(context); // Try with grid size and hotseat count @@ -114,7 +111,7 @@ public class AutoInstallsLayout { // Object Tags private static final String TAG_INCLUDE = "include"; - private static final String TAG_WORKSPACE = "workspace"; + public static final String TAG_WORKSPACE = "workspace"; private static final String TAG_APP_ICON = "appicon"; private static final String TAG_AUTO_INSTALL = "autoinstall"; private static final String TAG_FOLDER = "folder"; @@ -156,7 +153,7 @@ public class AutoInstallsLayout { protected final PackageManager mPackageManager; protected final Resources mSourceRes; - protected final int mLayoutId; + protected final Supplier<XmlPullParser> mInitialLayoutSupplier; private final InvariantDeviceProfile mIdp; private final int mRowCount; @@ -171,6 +168,12 @@ public class AutoInstallsLayout { public AutoInstallsLayout(Context context, AppWidgetHost appWidgetHost, LayoutParserCallback callback, Resources res, int layoutId, String rootTag) { + this(context, appWidgetHost, callback, res, () -> res.getXml(layoutId), rootTag); + } + + public AutoInstallsLayout(Context context, AppWidgetHost appWidgetHost, + LayoutParserCallback callback, Resources res, + Supplier<XmlPullParser> initialLayoutSupplier, String rootTag) { mContext = context; mAppWidgetHost = appWidgetHost; mCallback = callback; @@ -180,7 +183,7 @@ public class AutoInstallsLayout { mRootTag = rootTag; mSourceRes = res; - mLayoutId = layoutId; + mInitialLayoutSupplier = initialLayoutSupplier; mIdp = LauncherAppState.getIDP(context); mRowCount = mIdp.numRows; @@ -193,9 +196,9 @@ public class AutoInstallsLayout { public int loadLayout(SQLiteDatabase db, IntArray screenIds) { mDb = db; try { - return parseLayout(mLayoutId, screenIds); + return parseLayout(mInitialLayoutSupplier.get(), screenIds); } catch (Exception e) { - Log.e(TAG, "Error parsing layout: " + e); + Log.e(TAG, "Error parsing layout: ", e); return -1; } } @@ -203,9 +206,8 @@ public class AutoInstallsLayout { /** * Parses the layout and returns the number of elements added on the homescreen. */ - protected int parseLayout(int layoutId, IntArray screenIds) + protected int parseLayout(XmlPullParser parser, IntArray screenIds) throws XmlPullParserException, IOException { - XmlPullParser parser = mSourceRes.getXml(layoutId); beginDocument(parser, mRootTag); final int depth = parser.getDepth(); int type; @@ -248,7 +250,7 @@ public class AutoInstallsLayout { final int resId = getAttributeResourceValue(parser, ATTR_WORKSPACE, 0); if (resId != 0) { // recursively load some more favorites, why not? - return parseLayout(resId, screenIds); + return parseLayout(mSourceRes.getXml(resId), screenIds); } else { return 0; } diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index 39d93c8a2..f830301a3 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -34,6 +34,7 @@ import android.content.Intent; import android.content.OperationApplicationException; import android.content.SharedPreferences; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ProviderInfo; import android.content.res.Resources; import android.database.Cursor; import android.database.DatabaseUtils; @@ -51,8 +52,10 @@ import android.os.Process; import android.os.UserHandle; import android.os.UserManager; import android.provider.BaseColumns; +import android.provider.Settings; import android.text.TextUtils; import android.util.Log; +import android.util.Xml; import com.android.launcher3.AutoInstallsLayout.LayoutParserCallback; import com.android.launcher3.LauncherSettings.Favorites; @@ -63,15 +66,21 @@ import com.android.launcher3.model.DbDowngradeHelper; import com.android.launcher3.provider.LauncherDbUtils; import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction; import com.android.launcher3.provider.RestoreDbTask; +import com.android.launcher3.util.IOUtils; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.NoLocaleSQLiteHelper; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.Thunk; +import org.xmlpull.v1.XmlPullParser; + import java.io.File; import java.io.FileDescriptor; +import java.io.IOException; +import java.io.InputStream; import java.io.PrintWriter; +import java.io.StringReader; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; @@ -93,8 +102,6 @@ public class LauncherProvider extends ContentProvider { static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED"; - private static final String RESTRICTION_PACKAGE_NAME = "workspace.configuration.package.name"; - private final ChangeListenerWrapper mListenerWrapper = new ChangeListenerWrapper(); private Handler mListenerHandler; @@ -505,25 +512,40 @@ public class LauncherProvider extends ContentProvider { */ private AutoInstallsLayout createWorkspaceLoaderFromAppRestriction(AppWidgetHost widgetHost) { Context ctx = getContext(); - UserManager um = (UserManager) ctx.getSystemService(Context.USER_SERVICE); - Bundle bundle = um.getApplicationRestrictions(ctx.getPackageName()); - if (bundle == null) { + InvariantDeviceProfile grid = LauncherAppState.getIDP(ctx); + + String authority = Settings.Secure.getString(ctx.getContentResolver(), + "launcher3.layout.provider"); + if (TextUtils.isEmpty(authority)) { return null; } - String packageName = bundle.getString(RESTRICTION_PACKAGE_NAME); - if (packageName != null) { - try { - Resources targetResources = ctx.getPackageManager() - .getResourcesForApplication(packageName); - return AutoInstallsLayout.get(ctx, packageName, targetResources, - widgetHost, mOpenHelper); - } catch (NameNotFoundException e) { - Log.e(TAG, "Target package for restricted profile not found", e); - return null; - } + ProviderInfo pi = ctx.getPackageManager().resolveContentProvider(authority, 0); + if (pi == null) { + Log.e(TAG, "No provider found for authority " + authority); + return null; + } + Uri uri = new Uri.Builder().scheme("content").authority(authority).path("launcher_layout") + .appendQueryParameter("version", "1") + .appendQueryParameter("gridWidth", Integer.toString(grid.numColumns)) + .appendQueryParameter("gridHeight", Integer.toString(grid.numRows)) + .appendQueryParameter("hotseatSize", Integer.toString(grid.numHotseatIcons)) + .build(); + + try (InputStream in = ctx.getContentResolver().openInputStream(uri)) { + // Read the full xml so that we fail early in case of any IO error. + String layout = new String(IOUtils.toByteArray(in)); + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new StringReader(layout)); + + Log.d(TAG, "Loading layout from " + authority); + return new AutoInstallsLayout(ctx, widgetHost, mOpenHelper, + ctx.getPackageManager().getResourcesForApplication(pi.applicationInfo), + () -> parser, AutoInstallsLayout.TAG_WORKSPACE); + } catch (Exception e) { + Log.e(TAG, "Error getting layout stream from: " + authority , e); + return null; } - return null; } private DefaultLayoutParser getDefaultLayoutParser(AppWidgetHost widgetHost) { |