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

Commit af102b97 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Plumb Context#mUser to TextServicesManager to TextServicesManagerService"

parents f37f0cc3 9f141ee8
Loading
Loading
Loading
Loading
+4 −3
Original line number Original line Diff line number Diff line
@@ -439,10 +439,11 @@ final class SystemServiceRegistry {
            }});
            }});


        registerService(Context.TEXT_SERVICES_MANAGER_SERVICE, TextServicesManager.class,
        registerService(Context.TEXT_SERVICES_MANAGER_SERVICE, TextServicesManager.class,
                new StaticServiceFetcher<TextServicesManager>() {
                new CachedServiceFetcher<TextServicesManager>() {
            @Override
            @Override
            public TextServicesManager createService() {
            public TextServicesManager createService(ContextImpl ctx)
                return TextServicesManager.getInstance();
                    throws ServiceNotFoundException {
                return TextServicesManager.createInstance(ctx);
            }});
            }});


        registerService(Context.KEYGUARD_SERVICE, KeyguardManager.class,
        registerService(Context.KEYGUARD_SERVICE, KeyguardManager.class,
+4 −9
Original line number Original line Diff line number Diff line
@@ -27,7 +27,6 @@ import android.util.Log;


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


import dalvik.system.CloseGuard;
import dalvik.system.CloseGuard;
@@ -96,7 +95,7 @@ public class SpellCheckerSession {
    private static final int MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE = 2;
    private static final int MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE = 2;


    private final InternalListener mInternalListener;
    private final InternalListener mInternalListener;
    private final ITextServicesManager mTextServicesManager;
    private final TextServicesManager mTextServicesManager;
    private final SpellCheckerInfo mSpellCheckerInfo;
    private final SpellCheckerInfo mSpellCheckerInfo;
    @UnsupportedAppUsage
    @UnsupportedAppUsage
    private final SpellCheckerSessionListener mSpellCheckerSessionListener;
    private final SpellCheckerSessionListener mSpellCheckerSessionListener;
@@ -124,7 +123,7 @@ public class SpellCheckerSession {
     * @hide
     * @hide
     */
     */
    public SpellCheckerSession(
    public SpellCheckerSession(
            SpellCheckerInfo info, ITextServicesManager tsm, SpellCheckerSessionListener listener) {
            SpellCheckerInfo info, TextServicesManager tsm, SpellCheckerSessionListener listener) {
        if (info == null || listener == null || tsm == null) {
        if (info == null || listener == null || tsm == null) {
            throw new NullPointerException();
            throw new NullPointerException();
        }
        }
@@ -166,12 +165,8 @@ public class SpellCheckerSession {
     */
     */
    public void close() {
    public void close() {
        mGuard.close();
        mGuard.close();
        try {
        mSpellCheckerSessionListenerImpl.close();
        mSpellCheckerSessionListenerImpl.close();
        mTextServicesManager.finishSpellCheckerService(mSpellCheckerSessionListenerImpl);
        mTextServicesManager.finishSpellCheckerService(mSpellCheckerSessionListenerImpl);
        } catch (RemoteException e) {
            // do nothing
        }
    }
    }


    /**
    /**
+46 −10
Original line number Original line Diff line number Diff line
@@ -16,16 +16,20 @@


package android.view.textservice;
package android.view.textservice;


import android.annotation.NonNull;
import android.annotation.SystemService;
import android.annotation.SystemService;
import android.annotation.UnsupportedAppUsage;
import android.annotation.UnsupportedAppUsage;
import android.annotation.UserIdInt;
import android.content.Context;
import android.content.Context;
import android.os.Bundle;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
import android.os.ServiceManager.ServiceNotFoundException;
import android.os.UserHandle;
import android.util.Log;
import android.util.Log;
import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;


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


import java.util.Locale;
import java.util.Locale;
@@ -67,17 +71,41 @@ public final class TextServicesManager {
    private static final String TAG = TextServicesManager.class.getSimpleName();
    private static final String TAG = TextServicesManager.class.getSimpleName();
    private static final boolean DBG = false;
    private static final boolean DBG = false;


    /**
     * @deprecated Do not use. Just kept because of {@link UnsupportedAppUsage} in
     * {@link #getInstance()}.
     */
    @Deprecated
    private static TextServicesManager sInstance;
    private static TextServicesManager sInstance;


    private final ITextServicesManager mService;
    private final ITextServicesManager mService;


    private TextServicesManager() throws ServiceNotFoundException {
    @UserIdInt
    private final int mUserId;

    private TextServicesManager(@UserIdInt int userId) throws ServiceNotFoundException {
        mService = ITextServicesManager.Stub.asInterface(
        mService = ITextServicesManager.Stub.asInterface(
                ServiceManager.getServiceOrThrow(Context.TEXT_SERVICES_MANAGER_SERVICE));
                ServiceManager.getServiceOrThrow(Context.TEXT_SERVICES_MANAGER_SERVICE));
        mUserId = userId;
    }
    }


    /**
    /**
     * Retrieve the global TextServicesManager instance, creating it if it doesn't already exist.
     * The factory method of {@link TextServicesManager}.
     *
     * @param context {@link Context} from which {@link TextServicesManager} should be instantiated.
     * @return {@link TextServicesManager} that is associated with {@link Context#getUserId()}.
     * @throws ServiceNotFoundException When {@link TextServicesManager} is not available.
     * @hide
     */
    @NonNull
    public static TextServicesManager createInstance(@NonNull Context context)
            throws ServiceNotFoundException {
        return new TextServicesManager(context.getUserId());
    }

    /**
     * @deprecated Do not use. Just kept because of {@link UnsupportedAppUsage} in
     * {@link #getInstance()}.
     * @hide
     * @hide
     */
     */
    @UnsupportedAppUsage
    @UnsupportedAppUsage
@@ -85,7 +113,7 @@ public final class TextServicesManager {
        synchronized (TextServicesManager.class) {
        synchronized (TextServicesManager.class) {
            if (sInstance == null) {
            if (sInstance == null) {
                try {
                try {
                    sInstance = new TextServicesManager();
                    sInstance = new TextServicesManager(UserHandle.myUserId());
                } catch (ServiceNotFoundException e) {
                } catch (ServiceNotFoundException e) {
                    throw new IllegalStateException(e);
                    throw new IllegalStateException(e);
                }
                }
@@ -136,7 +164,7 @@ public final class TextServicesManager {


        final SpellCheckerInfo sci;
        final SpellCheckerInfo sci;
        try {
        try {
            sci = mService.getCurrentSpellChecker(null);
            sci = mService.getCurrentSpellChecker(mUserId, null);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            return null;
            return null;
        }
        }
@@ -174,9 +202,9 @@ public final class TextServicesManager {
        if (subtypeInUse == null) {
        if (subtypeInUse == null) {
            return null;
            return null;
        }
        }
        final SpellCheckerSession session = new SpellCheckerSession(sci, mService, listener);
        final SpellCheckerSession session = new SpellCheckerSession(sci, this, listener);
        try {
        try {
            mService.getSpellCheckerService(sci.getId(), subtypeInUse.getLocale(),
            mService.getSpellCheckerService(mUserId, sci.getId(), subtypeInUse.getLocale(),
                    session.getTextServicesSessionListener(),
                    session.getTextServicesSessionListener(),
                    session.getSpellCheckerSessionListener(), bundle);
                    session.getSpellCheckerSessionListener(), bundle);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
@@ -191,7 +219,7 @@ public final class TextServicesManager {
    @UnsupportedAppUsage
    @UnsupportedAppUsage
    public SpellCheckerInfo[] getEnabledSpellCheckers() {
    public SpellCheckerInfo[] getEnabledSpellCheckers() {
        try {
        try {
            final SpellCheckerInfo[] retval = mService.getEnabledSpellCheckers();
            final SpellCheckerInfo[] retval = mService.getEnabledSpellCheckers(mUserId);
            if (DBG) {
            if (DBG) {
                Log.d(TAG, "getEnabledSpellCheckers: " + (retval != null ? retval.length : "null"));
                Log.d(TAG, "getEnabledSpellCheckers: " + (retval != null ? retval.length : "null"));
            }
            }
@@ -208,7 +236,7 @@ public final class TextServicesManager {
    public SpellCheckerInfo getCurrentSpellChecker() {
    public SpellCheckerInfo getCurrentSpellChecker() {
        try {
        try {
            // Passing null as a locale for ICS
            // Passing null as a locale for ICS
            return mService.getCurrentSpellChecker(null);
            return mService.getCurrentSpellChecker(mUserId, null);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
            throw e.rethrowFromSystemServer();
        }
        }
@@ -221,7 +249,7 @@ public final class TextServicesManager {
    public SpellCheckerSubtype getCurrentSpellCheckerSubtype(
    public SpellCheckerSubtype getCurrentSpellCheckerSubtype(
            boolean allowImplicitlySelectedSubtype) {
            boolean allowImplicitlySelectedSubtype) {
        try {
        try {
            return mService.getCurrentSpellCheckerSubtype(allowImplicitlySelectedSubtype);
            return mService.getCurrentSpellCheckerSubtype(mUserId, allowImplicitlySelectedSubtype);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
            throw e.rethrowFromSystemServer();
        }
        }
@@ -233,7 +261,15 @@ public final class TextServicesManager {
    @UnsupportedAppUsage
    @UnsupportedAppUsage
    public boolean isSpellCheckerEnabled() {
    public boolean isSpellCheckerEnabled() {
        try {
        try {
            return mService.isSpellCheckerEnabled();
            return mService.isSpellCheckerEnabled(mUserId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    void finishSpellCheckerService(ISpellCheckerSessionListener listener) {
        try {
            mService.finishSpellCheckerService(mUserId, listener);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
            throw e.rethrowFromSystemServer();
        }
        }
+7 −6
Original line number Original line Diff line number Diff line
@@ -29,12 +29,13 @@ import android.view.textservice.SpellCheckerSubtype;
 * @hide
 * @hide
 */
 */
interface ITextServicesManager {
interface ITextServicesManager {
    SpellCheckerInfo getCurrentSpellChecker(String locale);
    SpellCheckerInfo getCurrentSpellChecker(int userId, String locale);
    SpellCheckerSubtype getCurrentSpellCheckerSubtype(boolean allowImplicitlySelectedSubtype);
    SpellCheckerSubtype getCurrentSpellCheckerSubtype(int userId,
    oneway void getSpellCheckerService(String sciId, in String locale,
            boolean allowImplicitlySelectedSubtype);
    oneway void getSpellCheckerService(int userId, String sciId, in String locale,
            in ITextServicesSessionListener tsListener,
            in ITextServicesSessionListener tsListener,
            in ISpellCheckerSessionListener scListener, in Bundle bundle);
            in ISpellCheckerSessionListener scListener, in Bundle bundle);
    oneway void finishSpellCheckerService(in ISpellCheckerSessionListener listener);
    oneway void finishSpellCheckerService(int userId, in ISpellCheckerSessionListener listener);
    boolean isSpellCheckerEnabled();
    boolean isSpellCheckerEnabled(int userId);
    SpellCheckerInfo[] getEnabledSpellCheckers();
    SpellCheckerInfo[] getEnabledSpellCheckers(int userId);
}
}
+27 −14
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.server.textservices;
package com.android.server.textservices;


import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;

import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.UserIdInt;
@@ -513,8 +515,8 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
    // TODO: Save SpellCheckerService by supported languages. Currently only one spell
    // TODO: Save SpellCheckerService by supported languages. Currently only one spell
    // checker is saved.
    // checker is saved.
    @Override
    @Override
    public SpellCheckerInfo getCurrentSpellChecker(String locale) {
    public SpellCheckerInfo getCurrentSpellChecker(@UserIdInt int userId, String locale) {
        int userId = UserHandle.getCallingUserId();
        verifyUser(userId);
        synchronized (mLock) {
        synchronized (mLock) {
            final TextServicesData tsd = getDataFromCallingUserIdLocked(userId);
            final TextServicesData tsd = getDataFromCallingUserIdLocked(userId);
            if (tsd == null) return null;
            if (tsd == null) return null;
@@ -527,11 +529,12 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
    // TODO: Save SpellCheckerSubtype by supported languages by looking at "locale".
    // TODO: Save SpellCheckerSubtype by supported languages by looking at "locale".
    @Override
    @Override
    public SpellCheckerSubtype getCurrentSpellCheckerSubtype(
    public SpellCheckerSubtype getCurrentSpellCheckerSubtype(
            boolean allowImplicitlySelectedSubtype) {
            @UserIdInt int userId, boolean allowImplicitlySelectedSubtype) {
        verifyUser(userId);

        final int subtypeHashCode;
        final int subtypeHashCode;
        final SpellCheckerInfo sci;
        final SpellCheckerInfo sci;
        final Locale systemLocale;
        final Locale systemLocale;
        final int userId = UserHandle.getCallingUserId();


        synchronized (mLock) {
        synchronized (mLock) {
            final TextServicesData tsd = getDataFromCallingUserIdLocked(userId);
            final TextServicesData tsd = getDataFromCallingUserIdLocked(userId);
@@ -591,17 +594,17 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
    }
    }


    @Override
    @Override
    public void getSpellCheckerService(String sciId, String locale,
    public void getSpellCheckerService(@UserIdInt int userId, String sciId, String locale,
            ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener,
            ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener,
            Bundle bundle) {
            Bundle bundle) {
        verifyUser(userId);
        if (TextUtils.isEmpty(sciId) || tsListener == null || scListener == null) {
        if (TextUtils.isEmpty(sciId) || tsListener == null || scListener == null) {
            Slog.e(TAG, "getSpellCheckerService: Invalid input.");
            Slog.e(TAG, "getSpellCheckerService: Invalid input.");
            return;
            return;
        }
        }
        int callingUserId = UserHandle.getCallingUserId();


        synchronized (mLock) {
        synchronized (mLock) {
            final TextServicesData tsd = getDataFromCallingUserIdLocked(callingUserId);
            final TextServicesData tsd = getDataFromCallingUserIdLocked(userId);
            if (tsd == null) return;
            if (tsd == null) return;


            HashMap<String, SpellCheckerInfo> spellCheckerMap = tsd.mSpellCheckerMap;
            HashMap<String, SpellCheckerInfo> spellCheckerMap = tsd.mSpellCheckerMap;
@@ -634,8 +637,8 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
    }
    }


    @Override
    @Override
    public boolean isSpellCheckerEnabled() {
    public boolean isSpellCheckerEnabled(@UserIdInt int userId) {
        int userId = UserHandle.getCallingUserId();
        verifyUser(userId);


        synchronized (mLock) {
        synchronized (mLock) {
            final TextServicesData tsd = getDataFromCallingUserIdLocked(userId);
            final TextServicesData tsd = getDataFromCallingUserIdLocked(userId);
@@ -671,11 +674,11 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
    }
    }


    @Override
    @Override
    public SpellCheckerInfo[] getEnabledSpellCheckers() {
    public SpellCheckerInfo[] getEnabledSpellCheckers(@UserIdInt int userId) {
        int callingUserId = UserHandle.getCallingUserId();
        verifyUser(userId);


        synchronized (mLock) {
        synchronized (mLock) {
            final TextServicesData tsd = getDataFromCallingUserIdLocked(callingUserId);
            final TextServicesData tsd = getDataFromCallingUserIdLocked(userId);
            if (tsd == null) return null;
            if (tsd == null) return null;


            ArrayList<SpellCheckerInfo> spellCheckerList = tsd.mSpellCheckerList;
            ArrayList<SpellCheckerInfo> spellCheckerList = tsd.mSpellCheckerList;
@@ -691,11 +694,12 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
    }
    }


    @Override
    @Override
    public void finishSpellCheckerService(ISpellCheckerSessionListener listener) {
    public void finishSpellCheckerService(@UserIdInt int userId,
            ISpellCheckerSessionListener listener) {
        if (DBG) {
        if (DBG) {
            Slog.d(TAG, "FinishSpellCheckerService");
            Slog.d(TAG, "FinishSpellCheckerService");
        }
        }
        int userId = UserHandle.getCallingUserId();
        verifyUser(userId);


        synchronized (mLock) {
        synchronized (mLock) {
            final TextServicesData tsd = getDataFromCallingUserIdLocked(userId);
            final TextServicesData tsd = getDataFromCallingUserIdLocked(userId);
@@ -716,6 +720,15 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
        }
        }
    }
    }


    private void verifyUser(@UserIdInt int userId) {
        final int callingUserId = UserHandle.getCallingUserId();
        if (userId != callingUserId) {
            mContext.enforceCallingPermission(INTERACT_ACROSS_USERS_FULL,
                    "Cross-user interaction requires INTERACT_ACROSS_USERS_FULL. userId=" + userId
                            + " callingUserId=" + callingUserId);
        }
    }

    private void setCurrentSpellCheckerLocked(@Nullable SpellCheckerInfo sci, TextServicesData tsd) {
    private void setCurrentSpellCheckerLocked(@Nullable SpellCheckerInfo sci, TextServicesData tsd) {
        final String sciId = (sci != null) ? sci.getId() : "";
        final String sciId = (sci != null) ? sci.getId() : "";
        if (DBG) {
        if (DBG) {