From 7f920b8d5ed41375641cc991a037499443dc9098 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 27 Jun 2018 15:47:49 -0700 Subject: [PATCH] Cleaning up build rules to simplify customizing derivative projects > Using {packageName} instead of hardcoding com.android.launcher3 in AndroidManifest.xml for strings which are dependent on packageName > Adding proguard rule to prevent obfuscating any overridable class > Making it easier to extend SettingsActivity by overriding the fragment class Change-Id: I5668c3f33b4cf20ad01d7f54b3d79cc0d268d391 --- AndroidManifest-common.xml | 48 +++++++++++++++++ AndroidManifest.xml | 49 ----------------- proguard.flags | 19 ++----- quickstep/AndroidManifest.xml | 6 +-- .../android/quickstep/OverviewCallbacks.java | 6 +-- .../android/quickstep/TaskOverlayFactory.java | 6 +-- res/values/config.xml | 6 +-- src/com/android/launcher3/AppFilter.java | 6 ++- src/com/android/launcher3/IconProvider.java | 6 ++- .../LauncherAppTransitionManager.java | 6 ++- .../launcher3/MainProcessInitializer.java | 5 +- .../android/launcher3/SettingsActivity.java | 23 +++++++- src/com/android/launcher3/Utilities.java | 20 ------- .../launcher3/graphics/DrawableFactory.java | 5 +- .../logging/UserEventDispatcher.java | 5 +- .../launcher3/util/InstantAppResolver.java | 5 +- .../launcher3/util/ResourceBasedOverride.java | 54 +++++++++++++++++++ .../uioverrides/WallpaperColorInfo.java | 2 +- .../dynamicui/ColorExtractionAlgorithm.java | 7 --- 19 files changed, 163 insertions(+), 121 deletions(-) create mode 100644 src/com/android/launcher3/util/ResourceBasedOverride.java diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml index 211e1ff37f..8f4d5bece5 100644 --- a/AndroidManifest-common.xml +++ b/AndroidManifest-common.xml @@ -44,6 +44,28 @@ + + + + + + + + + + + + + + + + + + + diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 3212980a05..4ac51ab788 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -26,29 +26,6 @@ Refer comments around specific entries on how to extend individual components. --> - - - - - - - - - - - - - - - - - - - - diff --git a/proguard.flags b/proguard.flags index e4011165e1..ddae07e0d9 100644 --- a/proguard.flags +++ b/proguard.flags @@ -97,30 +97,19 @@ # support jar. -keep class android.support.v7.widget.RecyclerView { *; } -# LauncherAppTransitionManager --keep class com.android.launcher3.LauncherAppTransitionManagerImpl { +# Preference fragments +-keep class ** extends android.preference.PreferenceFragment { public (...); } -# InstantAppResolver --keep class com.android.quickstep.InstantAppResolverImpl { - public (...); -} - -# MainProcessInitializer --keep class com.android.quickstep.QuickstepProcessInitializer { - public (...); -} - -# UserEventDispatcherExtension --keep class com.android.quickstep.logging.UserEventDispatcherExtension { +## Prevent obfuscating various overridable objects +-keep class ** implements com.android.launcher3.util.ResourceBasedOverride { public (...); } -keep interface com.android.launcher3.userevent.nano.LauncherLogProto.** { *; } - -keep interface com.android.launcher3.model.nano.LauncherDumpProto.** { *; } diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml index cb7485587d..74e0b1e777 100644 --- a/quickstep/AndroidManifest.xml +++ b/quickstep/AndroidManifest.xml @@ -24,6 +24,7 @@ + - + - diff --git a/quickstep/src/com/android/quickstep/OverviewCallbacks.java b/quickstep/src/com/android/quickstep/OverviewCallbacks.java index ac4a40b983..ef9c5c0d94 100644 --- a/quickstep/src/com/android/quickstep/OverviewCallbacks.java +++ b/quickstep/src/com/android/quickstep/OverviewCallbacks.java @@ -18,20 +18,20 @@ package com.android.quickstep; import android.content.Context; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.util.Preconditions; +import com.android.launcher3.util.ResourceBasedOverride; /** * Callbacks related to overview/quicksteps. */ -public class OverviewCallbacks { +public class OverviewCallbacks implements ResourceBasedOverride { private static OverviewCallbacks sInstance; public static OverviewCallbacks get(Context context) { Preconditions.assertUIThread(); if (sInstance == null) { - sInstance = Utilities.getOverrideObject(OverviewCallbacks.class, + sInstance = Overrides.getObject(OverviewCallbacks.class, context.getApplicationContext(), R.string.overview_callbacks_class); } return sInstance; diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java index 9d3ac6af6f..c272b1a7ef 100644 --- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java +++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java @@ -22,22 +22,22 @@ import android.support.annotation.AnyThread; import android.view.View; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.util.Preconditions; +import com.android.launcher3.util.ResourceBasedOverride; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; /** * Factory class to create and add an overlays on the TaskView */ -public class TaskOverlayFactory { +public class TaskOverlayFactory implements ResourceBasedOverride { private static TaskOverlayFactory sInstance; public static TaskOverlayFactory get(Context context) { Preconditions.assertUIThread(); if (sInstance == null) { - sInstance = Utilities.getOverrideObject(TaskOverlayFactory.class, + sInstance = Overrides.getObject(TaskOverlayFactory.class, context.getApplicationContext(), R.string.task_overlay_factory_class); } return sInstance; diff --git a/res/values/config.xml b/res/values/config.xml index f2d6c21816..f462b9c534 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -18,6 +18,9 @@ #Intent;action=android.intent.action.DELETE;launchFlags=0x10800000;end + + com.android.launcher3.SettingsActivity$LauncherSettingsFragment + @@ -92,9 +95,6 @@ - - - diff --git a/src/com/android/launcher3/AppFilter.java b/src/com/android/launcher3/AppFilter.java index 923835a679..9b6166ffcf 100644 --- a/src/com/android/launcher3/AppFilter.java +++ b/src/com/android/launcher3/AppFilter.java @@ -3,10 +3,12 @@ package com.android.launcher3; import android.content.ComponentName; import android.content.Context; -public class AppFilter { +import com.android.launcher3.util.ResourceBasedOverride; + +public class AppFilter implements ResourceBasedOverride { public static AppFilter newInstance(Context context) { - return Utilities.getOverrideObject(AppFilter.class, context, R.string.app_filter_class); + return Overrides.getObject(AppFilter.class, context, R.string.app_filter_class); } public boolean shouldShowApp(ComponentName app) { diff --git a/src/com/android/launcher3/IconProvider.java b/src/com/android/launcher3/IconProvider.java index b469a8f454..ed8d03c47a 100644 --- a/src/com/android/launcher3/IconProvider.java +++ b/src/com/android/launcher3/IconProvider.java @@ -5,14 +5,16 @@ import android.content.pm.LauncherActivityInfo; import android.graphics.drawable.Drawable; import android.os.Build; +import com.android.launcher3.util.ResourceBasedOverride; + import java.util.Locale; -public class IconProvider { +public class IconProvider implements ResourceBasedOverride { protected String mSystemState; public static IconProvider newInstance(Context context) { - IconProvider provider = Utilities.getOverrideObject( + IconProvider provider = Overrides.getObject( IconProvider.class, context, R.string.icon_provider_class); provider.updateSystemStateString(context); return provider; diff --git a/src/com/android/launcher3/LauncherAppTransitionManager.java b/src/com/android/launcher3/LauncherAppTransitionManager.java index 4037a23ff4..970e558786 100644 --- a/src/com/android/launcher3/LauncherAppTransitionManager.java +++ b/src/com/android/launcher3/LauncherAppTransitionManager.java @@ -23,13 +23,15 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.view.View; +import com.android.launcher3.util.ResourceBasedOverride; + /** * Manages the opening and closing app transitions from Launcher. */ -public class LauncherAppTransitionManager { +public class LauncherAppTransitionManager implements ResourceBasedOverride { public static LauncherAppTransitionManager newInstance(Context context) { - return Utilities.getOverrideObject(LauncherAppTransitionManager.class, + return Overrides.getObject(LauncherAppTransitionManager.class, context, R.string.app_transition_manager_class); } diff --git a/src/com/android/launcher3/MainProcessInitializer.java b/src/com/android/launcher3/MainProcessInitializer.java index 462eadb344..0028f97cd7 100644 --- a/src/com/android/launcher3/MainProcessInitializer.java +++ b/src/com/android/launcher3/MainProcessInitializer.java @@ -20,14 +20,15 @@ import android.content.Context; import com.android.launcher3.graphics.IconShapeOverride; import com.android.launcher3.logging.FileLog; +import com.android.launcher3.util.ResourceBasedOverride; /** * Utility class to handle one time initializations of the main process */ -public class MainProcessInitializer { +public class MainProcessInitializer implements ResourceBasedOverride { public static void initialize(Context context) { - Utilities.getOverrideObject( + Overrides.getObject( MainProcessInitializer.class, context, R.string.main_process_initializer_class) .init(context); } diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java index 32c198ab0a..8589b7ee63 100644 --- a/src/com/android/launcher3/SettingsActivity.java +++ b/src/com/android/launcher3/SettingsActivity.java @@ -24,6 +24,7 @@ import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; +import android.app.Fragment; import android.app.FragmentManager; import android.content.ComponentName; import android.content.ContentResolver; @@ -53,7 +54,8 @@ import java.util.Objects; /** * Settings activity for Launcher. Currently implements the following setting: Allow rotation */ -public class SettingsActivity extends Activity { +public class SettingsActivity extends Activity + implements PreferenceFragment.OnPreferenceStartFragmentCallback { private static final String ICON_BADGING_PREFERENCE_KEY = "pref_icon_badging"; /** Hidden field Settings.Secure.NOTIFICATION_BADGING */ @@ -71,9 +73,10 @@ public class SettingsActivity extends Activity { super.onCreate(savedInstanceState); if (savedInstanceState == null) { + Fragment f = Fragment.instantiate(this, getString(R.string.settings_fragment_name)); // Display the fragment as the main content. getFragmentManager().beginTransaction() - .replace(android.R.id.content, getNewFragment()) + .replace(android.R.id.content, f) .commit(); } } @@ -82,6 +85,22 @@ public class SettingsActivity extends Activity { return new LauncherSettingsFragment(); } + @Override + public boolean onPreferenceStartFragment( + PreferenceFragment preferenceFragment, Preference pref) { + Fragment f = Fragment.instantiate(this, pref.getFragment(), pref.getExtras()); + if (f instanceof DialogFragment) { + ((DialogFragment) f).show(getFragmentManager(), pref.getKey()); + } else { + getFragmentManager() + .beginTransaction() + .replace(android.R.id.content, f) + .addToBackStack(pref.getKey()) + .commit(); + } + return true; + } + /** * This fragment shows the launcher preferences. */ diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 7fe8d35cb6..8683b2103b 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -55,7 +55,6 @@ import com.android.launcher3.config.FeatureFlags; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collection; import java.util.HashSet; @@ -581,25 +580,6 @@ public final class Utilities { || e.getCause() instanceof DeadObjectException; } - public static T getOverrideObject(Class clazz, Context context, int resId) { - String className = context.getString(resId); - if (!TextUtils.isEmpty(className)) { - try { - Class cls = Class.forName(className); - return (T) cls.getDeclaredConstructor(Context.class).newInstance(context); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException - | ClassCastException | NoSuchMethodException | InvocationTargetException e) { - Log.e(TAG, "Bad overriden class", e); - } - } - - try { - return clazz.newInstance(); - } catch (InstantiationException|IllegalAccessException e) { - throw new RuntimeException(e); - } - } - /** * Returns a HashSet with a single element. We use this instead of Collections.singleton() * because HashSet ensures all operations, such as remove, are supported. diff --git a/src/com/android/launcher3/graphics/DrawableFactory.java b/src/com/android/launcher3/graphics/DrawableFactory.java index 34a4e2d771..bbc013d506 100644 --- a/src/com/android/launcher3/graphics/DrawableFactory.java +++ b/src/com/android/launcher3/graphics/DrawableFactory.java @@ -36,11 +36,12 @@ import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.allapps.AllAppsBackgroundDrawable; +import com.android.launcher3.util.ResourceBasedOverride; /** * Factory for creating new drawables. */ -public class DrawableFactory { +public class DrawableFactory implements ResourceBasedOverride { private static final String TAG = "DrawableFactory"; @@ -52,7 +53,7 @@ public class DrawableFactory { public static DrawableFactory get(Context context) { synchronized (LOCK) { if (sInstance == null) { - sInstance = Utilities.getOverrideObject(DrawableFactory.class, + sInstance = Overrides.getObject(DrawableFactory.class, context.getApplicationContext(), R.string.drawable_factory_class); } return sInstance; diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java index d1e1051eee..d9d3f6821d 100644 --- a/src/com/android/launcher3/logging/UserEventDispatcher.java +++ b/src/com/android/launcher3/logging/UserEventDispatcher.java @@ -51,6 +51,7 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Target; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.InstantAppResolver; import com.android.launcher3.util.LogConfig; +import com.android.launcher3.util.ResourceBasedOverride; import java.util.Locale; import java.util.UUID; @@ -61,7 +62,7 @@ import java.util.UUID; * * $ adb shell setprop log.tag.UserEvent VERBOSE */ -public class UserEventDispatcher { +public class UserEventDispatcher implements ResourceBasedOverride { private final static int MAXIMUM_VIEW_HIERARCHY_LEVEL = 5; @@ -78,7 +79,7 @@ public class UserEventDispatcher { uuidStr = UUID.randomUUID().toString(); sharedPrefs.edit().putString(UUID_STORAGE, uuidStr).apply(); } - UserEventDispatcher ued = Utilities.getOverrideObject(UserEventDispatcher.class, + UserEventDispatcher ued = Overrides.getObject(UserEventDispatcher.class, context.getApplicationContext(), R.string.user_event_dispatcher_class); ued.mDelegate = delegate; ued.mIsInLandscapeMode = dp.isVerticalBarLayout(); diff --git a/src/com/android/launcher3/util/InstantAppResolver.java b/src/com/android/launcher3/util/InstantAppResolver.java index 4485427f57..5dc7af855b 100644 --- a/src/com/android/launcher3/util/InstantAppResolver.java +++ b/src/com/android/launcher3/util/InstantAppResolver.java @@ -23,7 +23,6 @@ import android.util.Log; import com.android.launcher3.AppInfo; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import java.util.Collections; import java.util.List; @@ -31,10 +30,10 @@ import java.util.List; /** * A wrapper class to access instant app related APIs. */ -public class InstantAppResolver { +public class InstantAppResolver implements ResourceBasedOverride { public static InstantAppResolver newInstance(Context context) { - return Utilities.getOverrideObject( + return Overrides.getObject( InstantAppResolver.class, context, R.string.instant_app_resolver_class); } diff --git a/src/com/android/launcher3/util/ResourceBasedOverride.java b/src/com/android/launcher3/util/ResourceBasedOverride.java new file mode 100644 index 0000000000..e2c4992a44 --- /dev/null +++ b/src/com/android/launcher3/util/ResourceBasedOverride.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.util; + +import android.content.Context; +import android.text.TextUtils; +import android.util.Log; + +import java.lang.reflect.InvocationTargetException; + +/** + * An interface to indicate that a class is dynamically loaded using resource overlay, hence its + * class name and constructor should be preserved by proguard + */ +public interface ResourceBasedOverride { + + class Overrides { + + private static final String TAG = "Overrides"; + + public static T getObject( + Class clazz, Context context, int resId) { + String className = context.getString(resId); + if (!TextUtils.isEmpty(className)) { + try { + Class cls = Class.forName(className); + return (T) cls.getDeclaredConstructor(Context.class).newInstance(context); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException + | ClassCastException | NoSuchMethodException | InvocationTargetException e) { + Log.e(TAG, "Bad overriden class", e); + } + } + + try { + return clazz.newInstance(); + } catch (InstantiationException|IllegalAccessException e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/WallpaperColorInfo.java b/src_ui_overrides/com/android/launcher3/uioverrides/WallpaperColorInfo.java index 21070941bc..56e326002a 100644 --- a/src_ui_overrides/com/android/launcher3/uioverrides/WallpaperColorInfo.java +++ b/src_ui_overrides/com/android/launcher3/uioverrides/WallpaperColorInfo.java @@ -56,7 +56,7 @@ public class WallpaperColorInfo implements WallpaperManagerCompat.OnColorsChange private WallpaperColorInfo(Context context) { mWallpaperManager = WallpaperManagerCompat.getInstance(context); mWallpaperManager.addOnColorsChangedListener(this); - mExtractionType = ColorExtractionAlgorithm.newInstance(context); + mExtractionType = new ColorExtractionAlgorithm(); update(mWallpaperManager.getWallpaperColors(FLAG_SYSTEM)); } diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/dynamicui/ColorExtractionAlgorithm.java b/src_ui_overrides/com/android/launcher3/uioverrides/dynamicui/ColorExtractionAlgorithm.java index 0444212b85..21b324f07a 100644 --- a/src_ui_overrides/com/android/launcher3/uioverrides/dynamicui/ColorExtractionAlgorithm.java +++ b/src_ui_overrides/com/android/launcher3/uioverrides/dynamicui/ColorExtractionAlgorithm.java @@ -16,7 +16,6 @@ package com.android.launcher3.uioverrides.dynamicui; -import android.content.Context; import android.graphics.Color; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -25,7 +24,6 @@ import android.util.Log; import android.util.Pair; import android.util.Range; -import com.android.launcher3.R; import com.android.launcher3.Utilities; import java.util.Arrays; @@ -37,11 +35,6 @@ import java.util.List; **/ public class ColorExtractionAlgorithm { - public static ColorExtractionAlgorithm newInstance(Context context) { - return Utilities.getOverrideObject(ColorExtractionAlgorithm.class, - context.getApplicationContext(), R.string.color_extraction_impl_class); - } - private static final String TAG = "Tonal"; // Used for tonal palette fitting