Loading services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +3 −8 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ import com.android.server.autofill.AutofillManagerService.AutofillCompatState; import com.android.server.autofill.AutofillManagerService.SmartSuggestionMode; import com.android.server.autofill.ui.AutoFillUI; import com.android.server.infra.AbstractPerUserSystemService; import com.android.server.infra.SecureSettingsServiceNameResolver; import java.io.PrintWriter; import java.util.ArrayList; Loading Loading @@ -154,7 +155,8 @@ final class AutofillManagerServiceImpl AutofillManagerServiceImpl(AutofillManagerService master, Object lock, LocalLog requestsHistory, LocalLog uiLatencyHistory, LocalLog wtfHistory, int userId, AutoFillUI ui, AutofillCompatState autofillCompatState, boolean disabled) { super(master, lock, userId); super(master, new SecureSettingsServiceNameResolver(master.getContext(), userId, Settings.Secure.AUTOFILL_SERVICE), lock, userId); mRequestsHistory = requestsHistory; mUiLatencyHistory = uiLatencyHistory; Loading Loading @@ -190,11 +192,6 @@ final class AutofillManagerServiceImpl return mInfo.getServiceInfo(); } @Override // from PerUserSystemService protected String getDefaultComponentName() { return getComponentNameFromSettings(); } @Nullable String[] getUrlBarResourceIdsForCompatMode(@NonNull String packageName) { return mAutofillCompatState.getUrlBarResourceIds(packageName, mUserId); Loading Loading @@ -852,8 +849,6 @@ final class AutofillManagerServiceImpl pw.print(prefix); pw.print("Service Label: "); pw.println(getServiceLabelLocked()); pw.print(prefix); pw.print("Target SDK: "); pw.println(getTargedSdkLocked()); } pw.print(prefix); pw.print("Component from settings: "); pw.println(getComponentNameFromSettings()); pw.print(prefix); pw.print("Default component: "); pw.println(getContext() .getString(R.string.config_defaultAutofillService)); pw.print(prefix); pw.print("Field classification enabled: "); Loading services/core/java/com/android/server/infra/AbstractMasterSystemService.java +6 −4 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ import java.util.List; * <ul> * <li>Disabling the service when {@link UserManager} restrictions change. * <li>Refreshing the service when its underlying * {@link #getServiceSettingsProperty() Settings property} changed. * {@link #getSettingsProperty() Settings property} changed. * <li>Calling the service when other Settings properties changed. * </ul> * Loading Loading @@ -214,7 +214,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem } /** * Temporary sets the service implementation. * Temporarily sets the service implementation. * * <p>Typically used by Shell command and/or CTS tests. * Loading Loading @@ -473,8 +473,10 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem pw.print(" Verbose: "); pw.println(realVerbose); pw.print(prefix); pw.print("Disabled users: "); pw.println(mDisabledUsers); pw.print(prefix); pw.print("Allow instant service: "); pw.println(mAllowInstantService); pw.print(prefix); pw.print("Settings property: "); pw.println( getServiceSettingsProperty()); final String settingsProperty = getServiceSettingsProperty(); if (settingsProperty != null) { pw.print(prefix); pw.print("Settings property: "); pw.println(settingsProperty); } pw.print(prefix); pw.print("Cached services: "); if (size == 0) { pw.println("none"); Loading services/core/java/com/android/server/infra/AbstractPerUserSystemService.java +14 −103 Original line number Diff line number Diff line Loading @@ -26,17 +26,12 @@ import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ServiceInfo; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserManager; import android.provider.Settings; import android.text.TextUtils; import android.util.Slog; import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; Loading @@ -54,15 +49,14 @@ import java.io.PrintWriter; public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSystemService<S, M>, M extends AbstractMasterSystemService<M, S>> { /** Handler message to {@link #resetTemporaryServiceLocked()} */ private static final int MSG_RESET_TEMPORARY_SERVICE = 0; protected final @UserIdInt int mUserId; protected final Object mLock; protected final String mTag = getClass().getSimpleName(); protected final M mMaster; private final ServiceNameResolver mServiceNameResolver; /** * Whether service was disabled for user due to {@link UserManager} restrictions. */ Loading @@ -78,29 +72,13 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst @GuardedBy("mLock") private ServiceInfo mServiceInfo; /** * Temporary service name set by {@link #setTemporaryServiceLocked(String, int)}. * * <p>Typically used by Shell command and/or CTS tests. */ @GuardedBy("mLock") private String mTemporaryServiceName; /** * When the temporary service will expire (and reset back to the default). */ @GuardedBy("mLock") private long mTemporaryServiceExpiration; /** * Handler used to reset the temporary service name. */ @GuardedBy("mLock") private Handler mTemporaryHandler; protected AbstractPerUserSystemService(@NonNull M master, @NonNull Object lock, protected AbstractPerUserSystemService(@NonNull M master, @NonNull ServiceNameResolver serviceNamer, @NonNull Object lock, @UserIdInt int userId) { mMaster = master; mServiceNameResolver = serviceNamer; mServiceNameResolver .setOnTemporaryServiceNameChangedCallback(() -> updateLocked(mDisabled)); mLock = lock; mUserId = userId; } Loading Loading @@ -219,43 +197,18 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst } /** * Gets the current name of the service, which is either the * {@link #getDefaultComponentName() default service} or the * Gets the current name of the service, which is either the default service or the * {@link #setTemporaryServiceLocked(String, int) temporary one}. */ protected final String getComponentNameLocked() { if (mTemporaryServiceName != null) { // Always log it, as it should only be used on CTS or during development Slog.w(mTag, "getComponentName(): using temporary name " + mTemporaryServiceName); return mTemporaryServiceName; } return getDefaultComponentName(); } /** * Gets the name of the default component for the service. * * <p>Typically implemented by returning {@link #getComponentNameFromSettings()} or by using * a string from the system resources. */ @Nullable protected abstract String getDefaultComponentName(); /** * Gets this name of the remote service this service binds to as defined by {@link Settings}. */ @Nullable protected final String getComponentNameFromSettings() { final String property = mMaster.getServiceSettingsProperty(); return property == null ? null : Settings.Secure .getStringForUser(getContext().getContentResolver(), property, mUserId); return mServiceNameResolver.getServiceNameLocked(); } /** * Checks whether the current service for the user was temporarily set. */ public final boolean isTemporaryServiceSetLocked() { return mTemporaryServiceName != null; return mServiceNameResolver.isTemporaryLocked(); } /** Loading @@ -266,49 +219,14 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst * to the default component after this timeout expires). */ protected final void setTemporaryServiceLocked(@NonNull String componentName, int durationMs) { mTemporaryServiceName = componentName; if (mTemporaryHandler == null) { mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) { @Override public void handleMessage(Message msg) { if (msg.what == MSG_RESET_TEMPORARY_SERVICE) { synchronized (mLock) { resetTemporaryServiceLocked(); } } else { Slog.wtf(mTag, "invalid handler msg: " + msg); } } }; } else { removeResetTemporaryServiceMessageLocked(); } mTemporaryServiceExpiration = SystemClock.elapsedRealtime() + durationMs; mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_SERVICE, durationMs); updateLocked(mDisabled); } private void removeResetTemporaryServiceMessageLocked() { if (mMaster.verbose) { Slog.v(mTag, "setTemporaryServiceLocked(): removing old message"); } // NOTE: caller should already have checked it mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE); mServiceNameResolver.setTemporaryServiceLocked(componentName, durationMs); } /** * Resets the temporary service implementation to the default component. */ protected final void resetTemporaryServiceLocked() { Slog.i(mTag, "resetting temporary service from " + mTemporaryServiceName); mTemporaryServiceName = null; if (mTemporaryHandler != null) { removeResetTemporaryServiceMessageLocked(); mTemporaryHandler = null; } updateLocked(mDisabled); mServiceNameResolver.resetTemporaryServiceLocked(); } /** Loading Loading @@ -401,14 +319,7 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst pw.print(prefix); pw.print("Service UID: "); pw.println(mServiceInfo.applicationInfo.uid); } if (mTemporaryServiceName != null) { pw.print(prefix); pw.print("Temporary service name: "); pw.print(mTemporaryServiceName); final long ttl = mTemporaryServiceExpiration - SystemClock.elapsedRealtime(); pw.print(" (expires in "); TimeUtils.formatDuration(ttl, pw); pw.println(")"); pw.print(prefix); pw.print(prefix); pw.print("Default service name: "); pw.println(getDefaultComponentName()); } else { pw.print(prefix); pw.print("Service name: "); pw.println(getDefaultComponentName()); } pw.print(prefix); pw.print("Name resolver: "); mServiceNameResolver.dumpShortLocked(pw); pw.println(); } } services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java 0 → 100644 +170 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.infra; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.UserIdInt; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemClock; import android.text.TextUtils; import android.util.Slog; import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; import java.io.PrintWriter; /** * Gets the service name using a framework resources, temporarily changing the service if necessary * (typically during CTS tests or service development). * * @hide */ public final class FrameworkResourcesServiceNameResolver implements ServiceNameResolver { private static final String TAG = FrameworkResourcesServiceNameResolver.class.getSimpleName(); /** Handler message to {@link #resetTemporaryServiceLocked()} */ private static final int MSG_RESET_TEMPORARY_SERVICE = 0; private final @NonNull Context mContext; private final @NonNull @UserIdInt int mUserId; private final @NonNull Object mLock; private final @StringRes int mResourceId; private @Nullable Runnable mOnSetCallback; /** * Temporary service name set by {@link #setTemporaryServiceLocked(String, int)}. * * <p>Typically used by Shell command and/or CTS tests. */ @GuardedBy("mLock") @Nullable private String mTemporaryServiceName; /** * When the temporary service will expire (and reset back to the default). */ @GuardedBy("mLock") private long mTemporaryServiceExpiration; /** * Handler used to reset the temporary service name. */ @GuardedBy("mLock") private Handler mTemporaryHandler; public FrameworkResourcesServiceNameResolver(@NonNull Context context, @UserIdInt int userId, @NonNull Object lock, @StringRes int resourceId) { mLock = lock; mContext = context; mUserId = userId; mResourceId = resourceId; } @Override public void setOnTemporaryServiceNameChangedCallback(@NonNull Runnable callback) { this.mOnSetCallback = callback; } @Override public String getDefaultServiceName() { final String name = mContext.getString(mResourceId); return TextUtils.isEmpty(name) ? null : name; } @Override public String getServiceNameLocked() { if (mTemporaryServiceName != null) { // Always log it, as it should only be used on CTS or during development Slog.w(TAG, "getComponentName(): using temporary name " + mTemporaryServiceName); return mTemporaryServiceName; } else { return getDefaultServiceName(); } } @Override public boolean isTemporaryLocked() { return mTemporaryServiceName != null; } @Override public void setTemporaryServiceLocked(@NonNull String componentName, int durationMs) { mTemporaryServiceName = componentName; if (mTemporaryHandler == null) { mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) { @Override public void handleMessage(Message msg) { if (msg.what == MSG_RESET_TEMPORARY_SERVICE) { synchronized (mLock) { resetTemporaryServiceLocked(); } } else { Slog.wtf(TAG, "invalid handler msg: " + msg); } } }; } else { removeResetTemporaryServiceMessageLocked(); } mTemporaryServiceExpiration = SystemClock.elapsedRealtime() + durationMs; mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_SERVICE, durationMs); onServiceNameChanged(); } @Override public void resetTemporaryServiceLocked() { Slog.i(TAG, "resetting temporary service from " + mTemporaryServiceName); mTemporaryServiceName = null; if (mTemporaryHandler != null) { removeResetTemporaryServiceMessageLocked(); mTemporaryHandler = null; } onServiceNameChanged(); } // TODO(b/117779333): support proto @Override public void dumpShortLocked(@NonNull PrintWriter pw) { pw.print("FrameworkResourcesServiceNamer: resId="); pw.print(mResourceId); if (mTemporaryServiceName != null) { pw.print(", tmpName="); pw.print(mTemporaryServiceName); final long ttl = mTemporaryServiceExpiration - SystemClock.elapsedRealtime(); pw.print(" (expires in "); TimeUtils.formatDuration(ttl, pw); pw.print(")"); pw.print(", defaultName="); pw.println(getDefaultServiceName()); } else { pw.print(", serviceName="); pw.println(getDefaultServiceName()); } } private void onServiceNameChanged() { if (mOnSetCallback != null) { mOnSetCallback.run(); } } private void removeResetTemporaryServiceMessageLocked() { // NOTE: caller should already have checked it mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE); } } services/core/java/com/android/server/infra/SecureSettingsServiceNameResolver.java 0 → 100644 +57 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.infra; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.Context; import android.provider.Settings; import java.io.PrintWriter; /** * Gets the service name using a property from the {@link android.provider.Settings.Secure} * provider. * * @hide */ public final class SecureSettingsServiceNameResolver implements ServiceNameResolver { private final @NonNull Context mContext; private final @NonNull @UserIdInt int mUserId; @NonNull private final String mProperty; public SecureSettingsServiceNameResolver(@NonNull Context context, @UserIdInt int userId, @NonNull String property) { mContext = context; mUserId = userId; mProperty = property; } @Override public String getDefaultServiceName() { return Settings.Secure.getStringForUser(mContext.getContentResolver(), mProperty, mUserId); } // TODO(b/117779333): support proto @Override public void dumpShortLocked(@NonNull PrintWriter pw) { pw.print("SecureSettingsServiceNamer: prop="); pw.print(mProperty); pw.print(", value="); pw.println(getDefaultServiceName()); } } Loading
services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +3 −8 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ import com.android.server.autofill.AutofillManagerService.AutofillCompatState; import com.android.server.autofill.AutofillManagerService.SmartSuggestionMode; import com.android.server.autofill.ui.AutoFillUI; import com.android.server.infra.AbstractPerUserSystemService; import com.android.server.infra.SecureSettingsServiceNameResolver; import java.io.PrintWriter; import java.util.ArrayList; Loading Loading @@ -154,7 +155,8 @@ final class AutofillManagerServiceImpl AutofillManagerServiceImpl(AutofillManagerService master, Object lock, LocalLog requestsHistory, LocalLog uiLatencyHistory, LocalLog wtfHistory, int userId, AutoFillUI ui, AutofillCompatState autofillCompatState, boolean disabled) { super(master, lock, userId); super(master, new SecureSettingsServiceNameResolver(master.getContext(), userId, Settings.Secure.AUTOFILL_SERVICE), lock, userId); mRequestsHistory = requestsHistory; mUiLatencyHistory = uiLatencyHistory; Loading Loading @@ -190,11 +192,6 @@ final class AutofillManagerServiceImpl return mInfo.getServiceInfo(); } @Override // from PerUserSystemService protected String getDefaultComponentName() { return getComponentNameFromSettings(); } @Nullable String[] getUrlBarResourceIdsForCompatMode(@NonNull String packageName) { return mAutofillCompatState.getUrlBarResourceIds(packageName, mUserId); Loading Loading @@ -852,8 +849,6 @@ final class AutofillManagerServiceImpl pw.print(prefix); pw.print("Service Label: "); pw.println(getServiceLabelLocked()); pw.print(prefix); pw.print("Target SDK: "); pw.println(getTargedSdkLocked()); } pw.print(prefix); pw.print("Component from settings: "); pw.println(getComponentNameFromSettings()); pw.print(prefix); pw.print("Default component: "); pw.println(getContext() .getString(R.string.config_defaultAutofillService)); pw.print(prefix); pw.print("Field classification enabled: "); Loading
services/core/java/com/android/server/infra/AbstractMasterSystemService.java +6 −4 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ import java.util.List; * <ul> * <li>Disabling the service when {@link UserManager} restrictions change. * <li>Refreshing the service when its underlying * {@link #getServiceSettingsProperty() Settings property} changed. * {@link #getSettingsProperty() Settings property} changed. * <li>Calling the service when other Settings properties changed. * </ul> * Loading Loading @@ -214,7 +214,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem } /** * Temporary sets the service implementation. * Temporarily sets the service implementation. * * <p>Typically used by Shell command and/or CTS tests. * Loading Loading @@ -473,8 +473,10 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem pw.print(" Verbose: "); pw.println(realVerbose); pw.print(prefix); pw.print("Disabled users: "); pw.println(mDisabledUsers); pw.print(prefix); pw.print("Allow instant service: "); pw.println(mAllowInstantService); pw.print(prefix); pw.print("Settings property: "); pw.println( getServiceSettingsProperty()); final String settingsProperty = getServiceSettingsProperty(); if (settingsProperty != null) { pw.print(prefix); pw.print("Settings property: "); pw.println(settingsProperty); } pw.print(prefix); pw.print("Cached services: "); if (size == 0) { pw.println("none"); Loading
services/core/java/com/android/server/infra/AbstractPerUserSystemService.java +14 −103 Original line number Diff line number Diff line Loading @@ -26,17 +26,12 @@ import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ServiceInfo; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserManager; import android.provider.Settings; import android.text.TextUtils; import android.util.Slog; import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; Loading @@ -54,15 +49,14 @@ import java.io.PrintWriter; public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSystemService<S, M>, M extends AbstractMasterSystemService<M, S>> { /** Handler message to {@link #resetTemporaryServiceLocked()} */ private static final int MSG_RESET_TEMPORARY_SERVICE = 0; protected final @UserIdInt int mUserId; protected final Object mLock; protected final String mTag = getClass().getSimpleName(); protected final M mMaster; private final ServiceNameResolver mServiceNameResolver; /** * Whether service was disabled for user due to {@link UserManager} restrictions. */ Loading @@ -78,29 +72,13 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst @GuardedBy("mLock") private ServiceInfo mServiceInfo; /** * Temporary service name set by {@link #setTemporaryServiceLocked(String, int)}. * * <p>Typically used by Shell command and/or CTS tests. */ @GuardedBy("mLock") private String mTemporaryServiceName; /** * When the temporary service will expire (and reset back to the default). */ @GuardedBy("mLock") private long mTemporaryServiceExpiration; /** * Handler used to reset the temporary service name. */ @GuardedBy("mLock") private Handler mTemporaryHandler; protected AbstractPerUserSystemService(@NonNull M master, @NonNull Object lock, protected AbstractPerUserSystemService(@NonNull M master, @NonNull ServiceNameResolver serviceNamer, @NonNull Object lock, @UserIdInt int userId) { mMaster = master; mServiceNameResolver = serviceNamer; mServiceNameResolver .setOnTemporaryServiceNameChangedCallback(() -> updateLocked(mDisabled)); mLock = lock; mUserId = userId; } Loading Loading @@ -219,43 +197,18 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst } /** * Gets the current name of the service, which is either the * {@link #getDefaultComponentName() default service} or the * Gets the current name of the service, which is either the default service or the * {@link #setTemporaryServiceLocked(String, int) temporary one}. */ protected final String getComponentNameLocked() { if (mTemporaryServiceName != null) { // Always log it, as it should only be used on CTS or during development Slog.w(mTag, "getComponentName(): using temporary name " + mTemporaryServiceName); return mTemporaryServiceName; } return getDefaultComponentName(); } /** * Gets the name of the default component for the service. * * <p>Typically implemented by returning {@link #getComponentNameFromSettings()} or by using * a string from the system resources. */ @Nullable protected abstract String getDefaultComponentName(); /** * Gets this name of the remote service this service binds to as defined by {@link Settings}. */ @Nullable protected final String getComponentNameFromSettings() { final String property = mMaster.getServiceSettingsProperty(); return property == null ? null : Settings.Secure .getStringForUser(getContext().getContentResolver(), property, mUserId); return mServiceNameResolver.getServiceNameLocked(); } /** * Checks whether the current service for the user was temporarily set. */ public final boolean isTemporaryServiceSetLocked() { return mTemporaryServiceName != null; return mServiceNameResolver.isTemporaryLocked(); } /** Loading @@ -266,49 +219,14 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst * to the default component after this timeout expires). */ protected final void setTemporaryServiceLocked(@NonNull String componentName, int durationMs) { mTemporaryServiceName = componentName; if (mTemporaryHandler == null) { mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) { @Override public void handleMessage(Message msg) { if (msg.what == MSG_RESET_TEMPORARY_SERVICE) { synchronized (mLock) { resetTemporaryServiceLocked(); } } else { Slog.wtf(mTag, "invalid handler msg: " + msg); } } }; } else { removeResetTemporaryServiceMessageLocked(); } mTemporaryServiceExpiration = SystemClock.elapsedRealtime() + durationMs; mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_SERVICE, durationMs); updateLocked(mDisabled); } private void removeResetTemporaryServiceMessageLocked() { if (mMaster.verbose) { Slog.v(mTag, "setTemporaryServiceLocked(): removing old message"); } // NOTE: caller should already have checked it mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE); mServiceNameResolver.setTemporaryServiceLocked(componentName, durationMs); } /** * Resets the temporary service implementation to the default component. */ protected final void resetTemporaryServiceLocked() { Slog.i(mTag, "resetting temporary service from " + mTemporaryServiceName); mTemporaryServiceName = null; if (mTemporaryHandler != null) { removeResetTemporaryServiceMessageLocked(); mTemporaryHandler = null; } updateLocked(mDisabled); mServiceNameResolver.resetTemporaryServiceLocked(); } /** Loading Loading @@ -401,14 +319,7 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst pw.print(prefix); pw.print("Service UID: "); pw.println(mServiceInfo.applicationInfo.uid); } if (mTemporaryServiceName != null) { pw.print(prefix); pw.print("Temporary service name: "); pw.print(mTemporaryServiceName); final long ttl = mTemporaryServiceExpiration - SystemClock.elapsedRealtime(); pw.print(" (expires in "); TimeUtils.formatDuration(ttl, pw); pw.println(")"); pw.print(prefix); pw.print(prefix); pw.print("Default service name: "); pw.println(getDefaultComponentName()); } else { pw.print(prefix); pw.print("Service name: "); pw.println(getDefaultComponentName()); } pw.print(prefix); pw.print("Name resolver: "); mServiceNameResolver.dumpShortLocked(pw); pw.println(); } }
services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java 0 → 100644 +170 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.infra; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.UserIdInt; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemClock; import android.text.TextUtils; import android.util.Slog; import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; import java.io.PrintWriter; /** * Gets the service name using a framework resources, temporarily changing the service if necessary * (typically during CTS tests or service development). * * @hide */ public final class FrameworkResourcesServiceNameResolver implements ServiceNameResolver { private static final String TAG = FrameworkResourcesServiceNameResolver.class.getSimpleName(); /** Handler message to {@link #resetTemporaryServiceLocked()} */ private static final int MSG_RESET_TEMPORARY_SERVICE = 0; private final @NonNull Context mContext; private final @NonNull @UserIdInt int mUserId; private final @NonNull Object mLock; private final @StringRes int mResourceId; private @Nullable Runnable mOnSetCallback; /** * Temporary service name set by {@link #setTemporaryServiceLocked(String, int)}. * * <p>Typically used by Shell command and/or CTS tests. */ @GuardedBy("mLock") @Nullable private String mTemporaryServiceName; /** * When the temporary service will expire (and reset back to the default). */ @GuardedBy("mLock") private long mTemporaryServiceExpiration; /** * Handler used to reset the temporary service name. */ @GuardedBy("mLock") private Handler mTemporaryHandler; public FrameworkResourcesServiceNameResolver(@NonNull Context context, @UserIdInt int userId, @NonNull Object lock, @StringRes int resourceId) { mLock = lock; mContext = context; mUserId = userId; mResourceId = resourceId; } @Override public void setOnTemporaryServiceNameChangedCallback(@NonNull Runnable callback) { this.mOnSetCallback = callback; } @Override public String getDefaultServiceName() { final String name = mContext.getString(mResourceId); return TextUtils.isEmpty(name) ? null : name; } @Override public String getServiceNameLocked() { if (mTemporaryServiceName != null) { // Always log it, as it should only be used on CTS or during development Slog.w(TAG, "getComponentName(): using temporary name " + mTemporaryServiceName); return mTemporaryServiceName; } else { return getDefaultServiceName(); } } @Override public boolean isTemporaryLocked() { return mTemporaryServiceName != null; } @Override public void setTemporaryServiceLocked(@NonNull String componentName, int durationMs) { mTemporaryServiceName = componentName; if (mTemporaryHandler == null) { mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) { @Override public void handleMessage(Message msg) { if (msg.what == MSG_RESET_TEMPORARY_SERVICE) { synchronized (mLock) { resetTemporaryServiceLocked(); } } else { Slog.wtf(TAG, "invalid handler msg: " + msg); } } }; } else { removeResetTemporaryServiceMessageLocked(); } mTemporaryServiceExpiration = SystemClock.elapsedRealtime() + durationMs; mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_SERVICE, durationMs); onServiceNameChanged(); } @Override public void resetTemporaryServiceLocked() { Slog.i(TAG, "resetting temporary service from " + mTemporaryServiceName); mTemporaryServiceName = null; if (mTemporaryHandler != null) { removeResetTemporaryServiceMessageLocked(); mTemporaryHandler = null; } onServiceNameChanged(); } // TODO(b/117779333): support proto @Override public void dumpShortLocked(@NonNull PrintWriter pw) { pw.print("FrameworkResourcesServiceNamer: resId="); pw.print(mResourceId); if (mTemporaryServiceName != null) { pw.print(", tmpName="); pw.print(mTemporaryServiceName); final long ttl = mTemporaryServiceExpiration - SystemClock.elapsedRealtime(); pw.print(" (expires in "); TimeUtils.formatDuration(ttl, pw); pw.print(")"); pw.print(", defaultName="); pw.println(getDefaultServiceName()); } else { pw.print(", serviceName="); pw.println(getDefaultServiceName()); } } private void onServiceNameChanged() { if (mOnSetCallback != null) { mOnSetCallback.run(); } } private void removeResetTemporaryServiceMessageLocked() { // NOTE: caller should already have checked it mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE); } }
services/core/java/com/android/server/infra/SecureSettingsServiceNameResolver.java 0 → 100644 +57 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.infra; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.Context; import android.provider.Settings; import java.io.PrintWriter; /** * Gets the service name using a property from the {@link android.provider.Settings.Secure} * provider. * * @hide */ public final class SecureSettingsServiceNameResolver implements ServiceNameResolver { private final @NonNull Context mContext; private final @NonNull @UserIdInt int mUserId; @NonNull private final String mProperty; public SecureSettingsServiceNameResolver(@NonNull Context context, @UserIdInt int userId, @NonNull String property) { mContext = context; mUserId = userId; mProperty = property; } @Override public String getDefaultServiceName() { return Settings.Secure.getStringForUser(mContext.getContentResolver(), mProperty, mUserId); } // TODO(b/117779333): support proto @Override public void dumpShortLocked(@NonNull PrintWriter pw) { pw.print("SecureSettingsServiceNamer: prop="); pw.print(mProperty); pw.print(", value="); pw.println(getDefaultServiceName()); } }