Create feature factory interface & initial impl.

Creates the abstract class FeatureFactory and an AOSP implementation
called Factory.

Also creates a static library for generating logtags since we need to use the code generated
by the logtags in multiple packages now.

BUG: 27751878
Change-Id: I88d826333642d3efc252134c4facb7b1ca014f32
(cherry picked from commit 867bb9c07ab332fd9be67d1eeee3db796d9e0ffa)
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 53c97b5..56a9e54 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -102,6 +102,7 @@
 import com.android.settings.notification.ZenModeScheduleRuleSettings;
 import com.android.settings.notification.ZenModeSettings;
 import com.android.settings.notification.ZenModeVisualInterruptionSettings;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.print.PrintJobSettingsFragment;
 import com.android.settings.print.PrintSettingsFragment;
 import com.android.settings.search.DynamicIndexableContentMonitor;
@@ -681,6 +682,9 @@
             }
         }
 
+        // Will remove this line before submitting.
+        FeatureFactory.getFactory(this).createToastController().makeToast(this);
+
         if (DEBUG_TIMING) Log.d(LOG_TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
                 + " ms");
     }
diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java
new file mode 100644
index 0000000..a5e779d
--- /dev/null
+++ b/src/com/android/settings/overlay/FeatureFactory.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2016 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.settings.overlay;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.settings.R;
+
+/**
+ * Abstract class for creating feature controllers. Allows OEM implementations to define their own
+ * factories with their own controllers containing whatever code is needed to implement
+ * the features. To provide a factory implementation, implementors should override
+ * {@link R.string#config_featureFactory} in their override.
+ */
+public abstract class FeatureFactory {
+    private static final String LOG_TAG = "FeatureFactory";
+    private static final boolean DEBUG = false;
+
+    private static FeatureFactory sFactory;
+
+    /**
+     * Returns a factory for creating feature controllers. Creates the factory if it does not
+     * already exist. Uses the value of {@link R.string#config_featureFactory} to instantiate
+     * a factory implementation.
+     */
+    public static FeatureFactory getFactory(Context context) {
+        if (sFactory != null) {
+            return sFactory;
+        }
+
+        if (DEBUG) Log.d(LOG_TAG, "getFactory");
+        final String clsName = context.getString(R.string.config_featureFactory);
+        if (TextUtils.isEmpty(clsName)) {
+            throw new UnsupportedOperationException("No feature factory configured");
+        }
+        try {
+            sFactory = (FeatureFactory) context.getClassLoader().loadClass(clsName).newInstance();
+        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+            throw new FactoryNotFoundException(e);
+        }
+
+        if (DEBUG) Log.d(LOG_TAG, "started " + sFactory.getClass().getSimpleName());
+        return sFactory;
+    }
+
+    /**
+     * Creates stub controller that makes {@link android.widget.Toast}s.
+     * Will be removed before submitting.
+     */
+    public abstract ToastController createToastController();
+
+    public static class FactoryNotFoundException extends RuntimeException {
+        public FactoryNotFoundException(Throwable throwable) {
+            super("Unable to create factory. Did you misconfigure Proguard?", throwable);
+        }
+    }
+}
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
new file mode 100644
index 0000000..4220bc0
--- /dev/null
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 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.settings.overlay;
+
+import android.content.Context;
+import android.widget.Toast;
+
+/**
+ * {@link FeatureFactory} implementation for AOSP Settings.
+ */
+public class FeatureFactoryImpl extends FeatureFactory {
+    @Override
+    public ToastController createToastController() {
+        return new ToastController() {
+            @Override
+            public void makeToast(Context context) {
+                Toast.makeText(context, "Here's a piece of AOSP toast", Toast.LENGTH_LONG).show();
+            }
+        };
+    }
+}
diff --git a/src/com/android/settings/overlay/ToastController.java b/src/com/android/settings/overlay/ToastController.java
new file mode 100644
index 0000000..d009ce2
--- /dev/null
+++ b/src/com/android/settings/overlay/ToastController.java
@@ -0,0 +1,10 @@
+package com.android.settings.overlay;
+
+import android.content.Context;
+
+/**
+ * Will be removed before submitting. Just a proof of concept for review.
+ */
+public interface ToastController {
+    void makeToast(Context context);
+}