/*
 * Copyright (C) 2008 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.unit_tests.activity;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ConfigurationInfo;
import android.content.res.Configuration;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.Suppress;

import java.util.Iterator;
import java.util.List;

public class ActivityManagerTest extends AndroidTestCase {

    protected Context mContext;
    protected ActivityManager mActivityManager;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mContext = getContext();
        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
    }

    // TODO should write a test for getRecentTasks()
    // TODO should write a test for getRunningTasks()
    // TODO should write a test for getMemoryInfo()
    
    // TODO: Find a way to re-enable this.  It fails if any other app has failed during startup.
    // This is probably an OK assumption given the desired system status when we run unit tests,
    // but it's not necessarily the right assumption for a unit test.
    @Suppress
    public void disabledTestErrorTasksEmpty() throws Exception {
        
        List<ActivityManager.ProcessErrorStateInfo> errList;
        
        errList = mActivityManager.getProcessesInErrorState();
        
        // test: confirm list is empty
        assertNull(errList);
    }
    
    // TODO: Force an activity into an error state - then see if we can catch it here?
    @SmallTest
    public void testErrorTasksWithError() throws Exception {
        
        List<ActivityManager.ProcessErrorStateInfo> errList;
        
        // TODO force another process into an error condition.  How?
        
        // test: confirm error list length is at least 1 under varying query lengths
//      checkErrorListMax(1,-1);

        errList = mActivityManager.getProcessesInErrorState();

        // test: the list itself is healthy
        checkErrorListSanity(errList);

        // test: confirm our application shows up in the list
    }
    
    // TODO: Force an activity into an ANR state - then see if we can catch it here?
    @SmallTest
    public void testErrorTasksWithANR() throws Exception {
        
        List<ActivityManager.ProcessErrorStateInfo> errList;
        
        // TODO: force an application into an ANR state
        
        errList = mActivityManager.getProcessesInErrorState();

        // test: the list itself is healthy
        checkErrorListSanity(errList);

        // test: confirm our ANR'ing application shows up in the list
    }
    
    @SmallTest
    public void testGetDeviceConfigurationInfo() throws Exception {
        ConfigurationInfo config = mActivityManager.getDeviceConfigurationInfo();
        assertNotNull(config);
        // Validate values against configuration retrieved from resources
        Configuration vconfig = mContext.getResources().getConfiguration();
        assertNotNull(vconfig);
        assertEquals(config.reqKeyboardType, vconfig.keyboard);
        assertEquals(config.reqTouchScreen, vconfig.touchscreen);
        assertEquals(config.reqNavigation, vconfig.navigation);
        if (vconfig.navigation == Configuration.NAVIGATION_NONAV) {
            assertNotNull(config.reqInputFeatures & ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV);
        }
        if (vconfig.keyboard != Configuration.KEYBOARD_UNDEFINED) {
            assertNotNull(config.reqInputFeatures & ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD);
        }    
    }
    
    // If any entries in appear in the list, sanity check them against all running applications
    private void checkErrorListSanity(List<ActivityManager.ProcessErrorStateInfo> errList) {
        if (errList == null) return;
        
        Iterator<ActivityManager.ProcessErrorStateInfo> iter = errList.iterator();
        while (iter.hasNext()) {
            ActivityManager.ProcessErrorStateInfo info = iter.next();
            assertNotNull(info);
            // sanity checks
            assertTrue((info.condition == ActivityManager.ProcessErrorStateInfo.CRASHED) ||
                       (info.condition == ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING));
            // TODO look at each of these and consider a stronger test
            // TODO can we cross-check at the process name via some other API?
            // TODO is there a better test for strings, e.g. "assertIsLegalString")
            assertNotNull(info.processName);
            // reasonableness test for info.pid ?
            assertNotNull(info.longMsg);
            assertNotNull(info.shortMsg);
            // is there any reasonable test for the crashData?  Probably not. 
        }
    }
}

