/*
 * Copyright (C) 2006 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 android.app.activity;

import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ServiceInfo;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.frameworks.coretests.R;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;

/**
 * Tests for meta-data associated with application components.
 */
public class MetaDataTest extends AndroidTestCase {

    private void checkMetaData(ComponentName cn, PackageItemInfo ci)
            throws IOException, XmlPullParserException {
        assertNotNull("Unable to find component " + cn, ci);

        Bundle md = ci.metaData;
        assertNotNull("No meta data found", md);

        assertEquals("foo", md.getString("com.android.frameworks.coretests.string"));
        assertTrue(md.getBoolean("com.android.frameworks.coretests.boolean"));
        assertEquals(100, md.getInt("com.android.frameworks.coretests.integer"));
        assertEquals(0xff000000, md.getInt("com.android.frameworks.coretests.color"));

        assertEquals((double) 1001,
                Math.floor(md.getFloat("com.android.frameworks.coretests.float") * 10 + .5));

        assertEquals(R.xml.metadata, md.getInt("com.android.frameworks.coretests.reference"));

        XmlResourceParser xml = ci.loadXmlMetaData(mContext.getPackageManager(),
                "com.android.frameworks.coretests.reference");
        assertNotNull(xml);

        int type;
        while ((type = xml.next()) != XmlPullParser.START_TAG
                && type != XmlPullParser.END_DOCUMENT) {
        }
        assertEquals(XmlPullParser.START_TAG, type);
        assertEquals("thedata", xml.getName());

        // method 1: direct access
        final String rawAttr = xml.getAttributeValue(null, "rawText");
        assertEquals("some raw text", rawAttr);

        // method 2: direct access of typed value
        final int rawColorIntAttr = xml.getAttributeIntValue(null, "rawColor", 0);
        assertEquals(0xffffff00, rawColorIntAttr);
        final String rawColorStrAttr = xml.getAttributeValue(null, "rawColor");
        assertEquals("#ffffff00", rawColorStrAttr);

        // method 2: direct access of resource attribute
        final String nameSpace = "http://schemas.android.com/apk/res/android";
        final int colorIntAttr = xml.getAttributeIntValue(nameSpace, "color", 0);
        assertEquals(0xffff0000, colorIntAttr);
        final String colorStrAttr = xml.getAttributeValue(nameSpace, "color");
        assertEquals("#ffff0000", colorStrAttr);

        // method 3: styled access (borrowing an attr from view system here)
        TypedArray a = mContext.obtainStyledAttributes(xml,
                android.R.styleable.TextView);
        String styledAttr = a.getString(android.R.styleable.TextView_text);
        assertEquals("text", styledAttr);
        a.recycle();
        
        xml.close();
    }

    @SmallTest
    public void testActivityWithData() throws Exception {
        ComponentName cn = new ComponentName(mContext, LocalActivity.class);
        ActivityInfo ai = mContext.getPackageManager().getActivityInfo(
                cn, PackageManager.GET_META_DATA);

        checkMetaData(cn, ai);

        ai = mContext.getPackageManager().getActivityInfo(cn, 0);

        assertNull("Meta data returned when not requested", ai.metaData);
    }

    @SmallTest
    public void testReceiverWithData() throws Exception {
        ComponentName cn = new ComponentName(mContext, LocalReceiver.class);
        ActivityInfo ai = mContext.getPackageManager().getReceiverInfo(
                cn, PackageManager.GET_META_DATA);

        checkMetaData(cn, ai);

        ai = mContext.getPackageManager().getReceiverInfo(cn, 0);

        assertNull("Meta data returned when not requested", ai.metaData);
    }

    @SmallTest
    public void testServiceWithData() throws Exception {
        ComponentName cn = new ComponentName(mContext, LocalService.class);
        ServiceInfo si = mContext.getPackageManager().getServiceInfo(
                cn, PackageManager.GET_META_DATA);

        checkMetaData(cn, si);

        si = mContext.getPackageManager().getServiceInfo(cn, 0);

        assertNull("Meta data returned when not requested", si.metaData);
    }

    @MediumTest
    public void testProviderWithData() throws Exception {
        ComponentName cn = new ComponentName(mContext, LocalProvider.class);
        ProviderInfo pi = mContext.getPackageManager().resolveContentProvider(
                "com.android.frameworks.coretests.LocalProvider",
                PackageManager.GET_META_DATA);
        checkMetaData(cn, pi);

        pi = mContext.getPackageManager().resolveContentProvider(
                "com.android.frameworks.coretests.LocalProvider", 0);

        assertNull("Meta data returned when not requested", pi.metaData);
    }

    @SmallTest
    public void testPermissionWithData() throws Exception {
        ComponentName cn = new ComponentName("foo",
                "com.android.frameworks.coretests.permission.TEST_GRANTED");
        PermissionInfo pi = mContext.getPackageManager().getPermissionInfo(
                cn.getClassName(), PackageManager.GET_META_DATA);
        checkMetaData(cn, pi);

        pi = mContext.getPackageManager().getPermissionInfo(
                cn.getClassName(), 0);

        assertNull("Meta data returned when not requested", pi.metaData);
    }
}


