/*
 * Copyright (C) 2010 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.server;

import com.android.internal.content.PackageMonitor;

import android.app.AppGlobals;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Binder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.speech.RecognitionService;
import android.text.TextUtils;
import android.util.Slog;

import java.util.List;

public class RecognitionManagerService extends Binder {
    final static String TAG = "RecognitionManagerService";

    private final Context mContext;
    private final MyPackageMonitor mMonitor;
    private final IPackageManager mIPm;

    private static final boolean DEBUG = false;

    class MyPackageMonitor extends PackageMonitor {
        public void onSomePackagesChanged() {
            int userHandle = getChangingUserId();
            if (DEBUG) Slog.i(TAG, "onSomePackagesChanged user=" + userHandle);
            ComponentName comp = getCurRecognizer(userHandle);
            if (comp == null) {
                if (anyPackagesAppearing()) {
                    comp = findAvailRecognizer(null, userHandle);
                    if (comp != null) {
                        setCurRecognizer(comp, userHandle);
                    }
                }
                return;
            }

            int change = isPackageDisappearing(comp.getPackageName()); 
            if (change == PACKAGE_PERMANENT_CHANGE
                    || change == PACKAGE_TEMPORARY_CHANGE) {
                setCurRecognizer(findAvailRecognizer(null, userHandle), userHandle);
                
            } else if (isPackageModified(comp.getPackageName())) {
                setCurRecognizer(findAvailRecognizer(comp.getPackageName(), userHandle),
                        userHandle);
            }
        }
    }

    RecognitionManagerService(Context context) {
        mContext = context;
        mMonitor = new MyPackageMonitor();
        mMonitor.register(context, null, UserHandle.ALL, true);
        mIPm = AppGlobals.getPackageManager();
        IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
                filter, null, null);
    }

    public void systemReady() {
        initForUser(UserHandle.USER_OWNER);
    }

    private void initForUser(int userHandle) {
        if (DEBUG) Slog.i(TAG, "initForUser user=" + userHandle);
        ComponentName comp = getCurRecognizer(userHandle);
        ServiceInfo info = null;
        if (comp != null) {
            // See if the current recognizer is still available.
            try {
                info = mIPm.getServiceInfo(comp, 0, userHandle);
            } catch (RemoteException e) {
            }
        }
        if (info == null) {
            comp = findAvailRecognizer(null, userHandle);
            if (comp != null) {
                setCurRecognizer(comp, userHandle);
            }
        }
    }

    ComponentName findAvailRecognizer(String prefPackage, int userHandle) {
        List<ResolveInfo> available =
                mContext.getPackageManager().queryIntentServicesAsUser(
                        new Intent(RecognitionService.SERVICE_INTERFACE), 0, userHandle);
        int numAvailable = available.size();

        if (numAvailable == 0) {
            Slog.w(TAG, "no available voice recognition services found for user " + userHandle);
            return null;
        } else {
            if (prefPackage != null) {
                for (int i=0; i<numAvailable; i++) {
                    ServiceInfo serviceInfo = available.get(i).serviceInfo;
                    if (prefPackage.equals(serviceInfo.packageName)) {
                        return new ComponentName(serviceInfo.packageName, serviceInfo.name);
                    }
                }
            }
            if (numAvailable > 1) {
                Slog.w(TAG, "more than one voice recognition service found, picking first");
            }

            ServiceInfo serviceInfo = available.get(0).serviceInfo;
            return new ComponentName(serviceInfo.packageName, serviceInfo.name);
        }
    }

    ComponentName getCurRecognizer(int userHandle) {
        String curRecognizer = Settings.Secure.getStringForUser(
                mContext.getContentResolver(),
                Settings.Secure.VOICE_RECOGNITION_SERVICE, userHandle);
        if (TextUtils.isEmpty(curRecognizer)) {
            return null;
        }
        if (DEBUG) Slog.i(TAG, "getCurRecognizer curRecognizer=" + curRecognizer
                + " user=" + userHandle);
        return ComponentName.unflattenFromString(curRecognizer);
    }

    void setCurRecognizer(ComponentName comp, int userHandle) {
        Settings.Secure.putStringForUser(mContext.getContentResolver(),
                Settings.Secure.VOICE_RECOGNITION_SERVICE,
                comp != null ? comp.flattenToShortString() : "", userHandle);
        if (DEBUG) Slog.i(TAG, "setCurRecognizer comp=" + comp
                + " user=" + userHandle);
    }

    BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (DEBUG) Slog.i(TAG, "received " + action);
            if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
                int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                if (userHandle > 0) {
                    initForUser(userHandle);
                }
            }
        }
    };
}
