17f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet/*
27f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * Copyright (C) 2010 The Android Open Source Project
37f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet *
47f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License");
57f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * you may not use this file except in compliance with the License.
67f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * You may obtain a copy of the License at
77f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet *
87f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet *      http://www.apache.org/licenses/LICENSE-2.0
97f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet *
107f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * Unless required by applicable law or agreed to in writing, software
117f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS,
127f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * See the License for the specific language governing permissions and
147f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * limitations under the License.
157f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet */
167f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet
177f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohetpackage android.app;
187f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet
1919a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport com.android.ide.common.rendering.api.IProjectCallback;
209a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohetimport com.android.tools.layoutlib.annotations.LayoutlibDelegate;
217f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet
227f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohetimport android.content.Context;
237f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohetimport android.os.Bundle;
247f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet
257f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet/**
267f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * Delegate used to provide new implementation of a select few methods of {@link Fragment}
277f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet *
287f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * Through the layoutlib_create tool, the original  methods of Fragment have been replaced
297f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * by calls to methods of the same name in this delegate class.
307f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet *
317f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * The methods being re-implemented are the ones responsible for instantiating Fragment objects.
327f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * Because the classes of these objects are found in the project, these methods need access to
337f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * {@link IProjectCallback} object. They are however static methods, so the callback is set
347f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet * before the inflation through {@link #setProjectCallback(IProjectCallback)}.
357f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet */
367f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohetpublic class Fragment_Delegate {
377f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet
387f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet    private static IProjectCallback sProjectCallback;
397f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet
407f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet    /**
417f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * Sets the current {@link IProjectCallback} to be used to instantiate classes coming
427f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * from the project being rendered.
437f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     */
447f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet    public static void setProjectCallback(IProjectCallback projectCallback) {
457f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet        sProjectCallback = projectCallback;
467f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet    }
477f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet
487f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet    /**
497f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * Like {@link #instantiate(Context, String, Bundle)} but with a null
507f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * argument Bundle.
517f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     */
529a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
537f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet    /*package*/ static Fragment instantiate(Context context, String fname) {
547f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet        return instantiate(context, fname, null);
557f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet    }
567f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet
577f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet    /**
587f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * Create a new instance of a Fragment with the given class name.  This is
597f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * the same as calling its empty constructor.
607f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     *
617f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * @param context The calling context being used to instantiate the fragment.
627f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * This is currently just used to get its ClassLoader.
637f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * @param fname The class name of the fragment to instantiate.
647f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * @param args Bundle of arguments to supply to the fragment, which it
657f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * can retrieve with {@link #getArguments()}.  May be null.
667f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * @return Returns a new fragment instance.
677f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * @throws InstantiationException If there is a failure in instantiating
687f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * the given fragment class.  This is a runtime exception; it is not
697f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     * normally expected to happen.
707f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet     */
719a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
727f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet    /*package*/ static Fragment instantiate(Context context, String fname, Bundle args) {
737f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet        try {
747f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet            if (sProjectCallback != null) {
757f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                Fragment f = (Fragment) sProjectCallback.loadView(fname,
767f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                        new Class[0], new Object[0]);
777f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet
787f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                if (args != null) {
797f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                    args.setClassLoader(f.getClass().getClassLoader());
807f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                    f.mArguments = args;
817f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                }
827f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                return f;
837f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet            }
847f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet
857f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet            return null;
867f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet        } catch (ClassNotFoundException e) {
877f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
887f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                    + ": make sure class name exists, is public, and has an"
897f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                    + " empty constructor that is public", e);
907f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet        } catch (java.lang.InstantiationException e) {
917f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
927f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                    + ": make sure class name exists, is public, and has an"
937f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                    + " empty constructor that is public", e);
947f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet        } catch (IllegalAccessException e) {
957f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
967f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                    + ": make sure class name exists, is public, and has an"
977f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                    + " empty constructor that is public", e);
987f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet        } catch (Exception e) {
997f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
1007f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                    + ": make sure class name exists, is public, and has an"
1017f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet                    + " empty constructor that is public", e);
1027f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet        }
1037f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet    }
1047f7752439543db6e13c599bdd10cb10254c24528Xavier Ducrohet}
105