Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c1fbdfe authored by Jerome Gaillard's avatar Jerome Gaillard Committed by Android (Google) Code Review
Browse files

Merge "Override TextServicesManager in layoutlib"

parents c66cc516 f149ca78
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ public final class ServiceManager {
     * Is not supposed to return null, but that is fine for layoutlib.
     */
    public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
        return null;
        throw new ServiceNotFoundException(name);
    }

    /**
+342 −0
Original line number Diff line number Diff line
/*
 * 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 android.view.textservice;

import com.android.internal.textservice.ISpellCheckerSessionListener;
import com.android.internal.textservice.ITextServicesManager;
import com.android.internal.textservice.ITextServicesSessionListener;

import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;

import java.util.Locale;

/**
 * System API to the overall text services, which arbitrates interaction between applications
 * and text services. You can retrieve an instance of this interface with
 * {@link Context#getSystemService(String) Context.getSystemService()}.
 *
 * The user can change the current text services in Settings. And also applications can specify
 * the target text services.
 *
 * <h3>Architecture Overview</h3>
 *
 * <p>There are three primary parties involved in the text services
 * framework (TSF) architecture:</p>
 *
 * <ul>
 * <li> The <strong>text services manager</strong> as expressed by this class
 * is the central point of the system that manages interaction between all
 * other parts.  It is expressed as the client-side API here which exists
 * in each application context and communicates with a global system service
 * that manages the interaction across all processes.
 * <li> A <strong>text service</strong> implements a particular
 * interaction model allowing the client application to retrieve information of text.
 * The system binds to the current text service that is in use, causing it to be created and run.
 * <li> Multiple <strong>client applications</strong> arbitrate with the text service
 * manager for connections to text services.
 * </ul>
 *
 * <h3>Text services sessions</h3>
 * <ul>
 * <li>The <strong>spell checker session</strong> is one of the text services.
 * {@link android.view.textservice.SpellCheckerSession}</li>
 * </ul>
 *
 */
public final class TextServicesManager {
    private static final String TAG = TextServicesManager.class.getSimpleName();
    private static final boolean DBG = false;

    private static TextServicesManager sInstance;

    private final ITextServicesManager mService;

    private TextServicesManager() {
        mService = new FakeTextServicesManager();
    }

    /**
     * Retrieve the global TextServicesManager instance, creating it if it doesn't already exist.
     * @hide
     */
    public static TextServicesManager getInstance() {
        synchronized (TextServicesManager.class) {
            if (sInstance == null) {
                sInstance = new TextServicesManager();
            }
            return sInstance;
        }
    }

    /**
     * Returns the language component of a given locale string.
     */
    private static String parseLanguageFromLocaleString(String locale) {
        final int idx = locale.indexOf('_');
        if (idx < 0) {
            return locale;
        } else {
            return locale.substring(0, idx);
        }
    }

    /**
     * Get a spell checker session for the specified spell checker
     * @param locale the locale for the spell checker. If {@code locale} is null and
     * referToSpellCheckerLanguageSettings is true, the locale specified in Settings will be
     * returned. If {@code locale} is not null and referToSpellCheckerLanguageSettings is true,
     * the locale specified in Settings will be returned only when it is same as {@code locale}.
     * Exceptionally, when referToSpellCheckerLanguageSettings is true and {@code locale} is
     * only language (e.g. "en"), the specified locale in Settings (e.g. "en_US") will be
     * selected.
     * @param listener a spell checker session lister for getting results from a spell checker.
     * @param referToSpellCheckerLanguageSettings if true, the session for one of enabled
     * languages in settings will be returned.
     * @return the spell checker session of the spell checker
     */
    public SpellCheckerSession newSpellCheckerSession(Bundle bundle, Locale locale,
            SpellCheckerSessionListener listener, boolean referToSpellCheckerLanguageSettings) {
        if (listener == null) {
            throw new NullPointerException();
        }
        if (!referToSpellCheckerLanguageSettings && locale == null) {
            throw new IllegalArgumentException("Locale should not be null if you don't refer"
                    + " settings.");
        }

        if (referToSpellCheckerLanguageSettings && !isSpellCheckerEnabled()) {
            return null;
        }

        final SpellCheckerInfo sci;
        try {
            sci = mService.getCurrentSpellChecker(null);
        } catch (RemoteException e) {
            return null;
        }
        if (sci == null) {
            return null;
        }
        SpellCheckerSubtype subtypeInUse = null;
        if (referToSpellCheckerLanguageSettings) {
            subtypeInUse = getCurrentSpellCheckerSubtype(true);
            if (subtypeInUse == null) {
                return null;
            }
            if (locale != null) {
                final String subtypeLocale = subtypeInUse.getLocale();
                final String subtypeLanguage = parseLanguageFromLocaleString(subtypeLocale);
                if (subtypeLanguage.length() < 2 || !locale.getLanguage().equals(subtypeLanguage)) {
                    return null;
                }
            }
        } else {
            final String localeStr = locale.toString();
            for (int i = 0; i < sci.getSubtypeCount(); ++i) {
                final SpellCheckerSubtype subtype = sci.getSubtypeAt(i);
                final String tempSubtypeLocale = subtype.getLocale();
                final String tempSubtypeLanguage = parseLanguageFromLocaleString(tempSubtypeLocale);
                if (tempSubtypeLocale.equals(localeStr)) {
                    subtypeInUse = subtype;
                    break;
                } else if (tempSubtypeLanguage.length() >= 2 &&
                        locale.getLanguage().equals(tempSubtypeLanguage)) {
                    subtypeInUse = subtype;
                }
            }
        }
        if (subtypeInUse == null) {
            return null;
        }
        final SpellCheckerSession session = new SpellCheckerSession(
                sci, mService, listener, subtypeInUse);
        try {
            mService.getSpellCheckerService(sci.getId(), subtypeInUse.getLocale(),
                    session.getTextServicesSessionListener(),
                    session.getSpellCheckerSessionListener(), bundle);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        return session;
    }

    /**
     * @hide
     */
    public SpellCheckerInfo[] getEnabledSpellCheckers() {
        try {
            final SpellCheckerInfo[] retval = mService.getEnabledSpellCheckers();
            if (DBG) {
                Log.d(TAG, "getEnabledSpellCheckers: " + (retval != null ? retval.length : "null"));
            }
            return retval;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * @hide
     */
    public SpellCheckerInfo getCurrentSpellChecker() {
        try {
            // Passing null as a locale for ICS
            return mService.getCurrentSpellChecker(null);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * @hide
     */
    public void setCurrentSpellChecker(SpellCheckerInfo sci) {
        try {
            if (sci == null) {
                throw new NullPointerException("SpellCheckerInfo is null.");
            }
            mService.setCurrentSpellChecker(null, sci.getId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * @hide
     */
    public SpellCheckerSubtype getCurrentSpellCheckerSubtype(
            boolean allowImplicitlySelectedSubtype) {
        try {
            // Passing null as a locale until we support multiple enabled spell checker subtypes.
            return mService.getCurrentSpellCheckerSubtype(null, allowImplicitlySelectedSubtype);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * @hide
     */
    public void setSpellCheckerSubtype(SpellCheckerSubtype subtype) {
        try {
            final int hashCode;
            if (subtype == null) {
                hashCode = 0;
            } else {
                hashCode = subtype.hashCode();
            }
            mService.setCurrentSpellCheckerSubtype(null, hashCode);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * @hide
     */
    public void setSpellCheckerEnabled(boolean enabled) {
        try {
            mService.setSpellCheckerEnabled(enabled);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * @hide
     */
    public boolean isSpellCheckerEnabled() {
        try {
            return mService.isSpellCheckerEnabled();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    private static class FakeTextServicesManager implements ITextServicesManager {

        @Override
        public void finishSpellCheckerService(ISpellCheckerSessionListener arg0)
                throws RemoteException {
            // TODO Auto-generated method stub

        }

        @Override
        public SpellCheckerInfo getCurrentSpellChecker(String arg0) throws RemoteException {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public SpellCheckerSubtype getCurrentSpellCheckerSubtype(String arg0, boolean arg1)
                throws RemoteException {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public SpellCheckerInfo[] getEnabledSpellCheckers() throws RemoteException {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void getSpellCheckerService(String arg0, String arg1,
                ITextServicesSessionListener arg2, ISpellCheckerSessionListener arg3, Bundle arg4)
                throws RemoteException {
            // TODO Auto-generated method stub

        }

        @Override
        public boolean isSpellCheckerEnabled() throws RemoteException {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public void setCurrentSpellChecker(String arg0, String arg1) throws RemoteException {
            // TODO Auto-generated method stub

        }

        @Override
        public void setCurrentSpellCheckerSubtype(String arg0, int arg1) throws RemoteException {
            // TODO Auto-generated method stub

        }

        @Override
        public void setSpellCheckerEnabled(boolean arg0) throws RemoteException {
            // TODO Auto-generated method stub

        }

        @Override
        public IBinder asBinder() {
            // TODO Auto-generated method stub
            return null;
        }

    }
}
 No newline at end of file
+0 −111
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 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.internal.textservice;

import com.android.tools.layoutlib.annotations.LayoutlibDelegate;

import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.textservice.SpellCheckerInfo;
import android.view.textservice.SpellCheckerSubtype;


/**
 * Delegate used to provide new implementation of a select few methods of
 * {@link ITextServicesManager$Stub}
 *
 * Through the layoutlib_create tool, the original  methods of Stub have been replaced
 * by calls to methods of the same name in this delegate class.
 *
 */
public class ITextServicesManager_Stub_Delegate {

    @LayoutlibDelegate
    public static ITextServicesManager asInterface(IBinder obj) {
        // ignore the obj and return a fake interface implementation
        return new FakeTextServicesManager();
    }

    private static class FakeTextServicesManager implements ITextServicesManager {

        @Override
        public void finishSpellCheckerService(ISpellCheckerSessionListener arg0)
                throws RemoteException {
            // TODO Auto-generated method stub

        }

        @Override
        public SpellCheckerInfo getCurrentSpellChecker(String arg0) throws RemoteException {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public SpellCheckerSubtype getCurrentSpellCheckerSubtype(String arg0, boolean arg1)
                throws RemoteException {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public SpellCheckerInfo[] getEnabledSpellCheckers() throws RemoteException {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void getSpellCheckerService(String arg0, String arg1,
                ITextServicesSessionListener arg2, ISpellCheckerSessionListener arg3, Bundle arg4)
                throws RemoteException {
            // TODO Auto-generated method stub

        }

        @Override
        public boolean isSpellCheckerEnabled() throws RemoteException {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public void setCurrentSpellChecker(String arg0, String arg1) throws RemoteException {
            // TODO Auto-generated method stub

        }

        @Override
        public void setCurrentSpellCheckerSubtype(String arg0, int arg1) throws RemoteException {
            // TODO Auto-generated method stub

        }

        @Override
        public void setSpellCheckerEnabled(boolean arg0) throws RemoteException {
            // TODO Auto-generated method stub

        }

        @Override
        public IBinder asBinder() {
            // TODO Auto-generated method stub
            return null;
        }

    }
 }
+1 −1
Original line number Diff line number Diff line
@@ -235,7 +235,6 @@ public final class CreateInfo implements ICreateInfo {
        "android.view.ViewGroup#drawChild",
        "com.android.internal.view.menu.MenuBuilder#createNewMenuItem",
        "com.android.internal.util.XmlUtils#convertValueToInt",
        "com.android.internal.textservice.ITextServicesManager$Stub#asInterface",
        "dalvik.system.VMRuntime#newUnpaddedArray",
        "libcore.io.MemoryMappedFile#mmapRO",
        "libcore.io.MemoryMappedFile#close",
@@ -304,6 +303,7 @@ public final class CreateInfo implements ICreateInfo {
    private final static String[] RENAMED_CLASSES =
        new String[] {
            "android.os.ServiceManager",                       "android.os._Original_ServiceManager",
            "android.view.textservice.TextServicesManager",    "android.view.textservice._Original_TextServicesManager",
            "android.util.LruCache",                           "android.util._Original_LruCache",
            "android.view.SurfaceView",                        "android.view._Original_SurfaceView",
            "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager",