Merge "Reduce unnecessary overhead of SystemUiContext" into sc-v2-dev

This commit is contained in:
Riddle Hsu
2021-12-10 03:00:52 +00:00
committed by Android (Google) Code Review
4 changed files with 44 additions and 25 deletions

View File

@@ -321,7 +321,8 @@ public final class ActivityThread extends ClientTransactionHandler
@UnsupportedAppUsage @UnsupportedAppUsage
private ContextImpl mSystemContext; private ContextImpl mSystemContext;
private final SparseArray<ContextImpl> mDisplaySystemUiContexts = new SparseArray<>(); @GuardedBy("this")
private SparseArray<ContextImpl> mDisplaySystemUiContexts;
@UnsupportedAppUsage @UnsupportedAppUsage
static volatile IPackageManager sPackageManager; static volatile IPackageManager sPackageManager;
@@ -2650,7 +2651,6 @@ public final class ActivityThread extends ClientTransactionHandler
} }
} }
@Override
@NonNull @NonNull
public ContextImpl getSystemUiContext() { public ContextImpl getSystemUiContext() {
return getSystemUiContext(DEFAULT_DISPLAY); return getSystemUiContext(DEFAULT_DISPLAY);
@@ -2664,6 +2664,9 @@ public final class ActivityThread extends ClientTransactionHandler
@NonNull @NonNull
public ContextImpl getSystemUiContext(int displayId) { public ContextImpl getSystemUiContext(int displayId) {
synchronized (this) { synchronized (this) {
if (mDisplaySystemUiContexts == null) {
mDisplaySystemUiContexts = new SparseArray<>();
}
ContextImpl systemUiContext = mDisplaySystemUiContexts.get(displayId); ContextImpl systemUiContext = mDisplaySystemUiContexts.get(displayId);
if (systemUiContext == null) { if (systemUiContext == null) {
systemUiContext = ContextImpl.createSystemUiContext(getSystemContext(), displayId); systemUiContext = ContextImpl.createSystemUiContext(getSystemContext(), displayId);
@@ -2673,6 +2676,15 @@ public final class ActivityThread extends ClientTransactionHandler
} }
} }
@Nullable
@Override
public ContextImpl getSystemUiContextNoCreate() {
synchronized (this) {
if (mDisplaySystemUiContexts == null) return null;
return mDisplaySystemUiContexts.get(DEFAULT_DISPLAY);
}
}
public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
synchronized (this) { synchronized (this) {
getSystemContext().installSystemApplicationInfo(info, classLoader); getSystemContext().installSystemApplicationInfo(info, classLoader);

View File

@@ -28,7 +28,7 @@ import java.util.ArrayList;
interface ActivityThreadInternal { interface ActivityThreadInternal {
ContextImpl getSystemContext(); ContextImpl getSystemContext();
ContextImpl getSystemUiContext(); ContextImpl getSystemUiContextNoCreate();
boolean isInDensityCompatMode(); boolean isInDensityCompatMode();

View File

@@ -154,9 +154,12 @@ class ConfigurationController {
int configDiff; int configDiff;
boolean equivalent; boolean equivalent;
// Get theme outside of synchronization to avoid nested lock.
final Resources.Theme systemTheme = mActivityThread.getSystemContext().getTheme();
final ContextImpl systemUiContext = mActivityThread.getSystemUiContextNoCreate();
final Resources.Theme systemUiTheme =
systemUiContext != null ? systemUiContext.getTheme() : null;
synchronized (mResourcesManager) { synchronized (mResourcesManager) {
final Resources.Theme systemTheme = mActivityThread.getSystemContext().getTheme();
final Resources.Theme systemUiTheme = mActivityThread.getSystemUiContext().getTheme();
if (mPendingConfiguration != null) { if (mPendingConfiguration != null) {
if (!mPendingConfiguration.isOtherSeqNewer(config)) { if (!mPendingConfiguration.isOtherSeqNewer(config)) {
config = mPendingConfiguration; config = mPendingConfiguration;
@@ -207,7 +210,8 @@ class ConfigurationController {
systemTheme.rebase(); systemTheme.rebase();
} }
if ((systemUiTheme.getChangingConfigurations() & configDiff) != 0) { if (systemUiTheme != null
&& (systemUiTheme.getChangingConfigurations() & configDiff) != 0) {
systemUiTheme.rebase(); systemUiTheme.rebase();
} }
} }

View File

@@ -173,7 +173,7 @@ class WindowContextListenerController {
@VisibleForTesting @VisibleForTesting
class WindowContextListenerImpl implements WindowContainerListener { class WindowContextListenerImpl implements WindowContainerListener {
@NonNull private final IBinder mClientToken; @NonNull private final IWindowToken mClientToken;
private final int mOwnerUid; private final int mOwnerUid;
@NonNull private WindowContainer<?> mContainer; @NonNull private WindowContainer<?> mContainer;
/** /**
@@ -193,7 +193,7 @@ class WindowContextListenerController {
private WindowContextListenerImpl(IBinder clientToken, WindowContainer<?> container, private WindowContextListenerImpl(IBinder clientToken, WindowContainer<?> container,
int ownerUid, @WindowType int type, @Nullable Bundle options) { int ownerUid, @WindowType int type, @Nullable Bundle options) {
mClientToken = clientToken; mClientToken = IWindowToken.Stub.asInterface(clientToken);
mContainer = Objects.requireNonNull(container); mContainer = Objects.requireNonNull(container);
mOwnerUid = ownerUid; mOwnerUid = ownerUid;
mType = type; mType = type;
@@ -205,7 +205,7 @@ class WindowContextListenerController {
mDeathRecipient = deathRecipient; mDeathRecipient = deathRecipient;
} catch (RemoteException e) { } catch (RemoteException e) {
ProtoLog.e(WM_ERROR, "Could not register window container listener token=%s, " ProtoLog.e(WM_ERROR, "Could not register window container listener token=%s, "
+ "container=%s", mClientToken, mContainer); + "container=%s", clientToken, mContainer);
} }
} }
@@ -228,17 +228,17 @@ class WindowContextListenerController {
} }
private void register() { private void register() {
final IBinder token = mClientToken.asBinder();
if (mDeathRecipient == null) { if (mDeathRecipient == null) {
throw new IllegalStateException("Invalid client token: " + mClientToken); throw new IllegalStateException("Invalid client token: " + token);
} }
mListeners.putIfAbsent(mClientToken, this); mListeners.putIfAbsent(token, this);
mContainer.registerWindowContainerListener(this); mContainer.registerWindowContainerListener(this);
reportConfigToWindowTokenClient();
} }
private void unregister() { private void unregister() {
mContainer.unregisterWindowContainerListener(this); mContainer.unregisterWindowContainerListener(this);
mListeners.remove(mClientToken); mListeners.remove(mClientToken.asBinder());
} }
private void clear() { private void clear() {
@@ -258,19 +258,24 @@ class WindowContextListenerController {
private void reportConfigToWindowTokenClient() { private void reportConfigToWindowTokenClient() {
if (mDeathRecipient == null) { if (mDeathRecipient == null) {
throw new IllegalStateException("Invalid client token: " + mClientToken); throw new IllegalStateException("Invalid client token: " + mClientToken.asBinder());
}
final DisplayContent dc = mContainer.getDisplayContent();
if (!dc.isReady()) {
// Do not report configuration when booting. The latest configuration will be sent
// when WindowManagerService#displayReady().
return;
} }
// If the display of window context associated window container is suspended, don't // If the display of window context associated window container is suspended, don't
// report the configuration update. Note that we still dispatch the configuration update // report the configuration update. Note that we still dispatch the configuration update
// to WindowProviderService to make it compatible with Service#onConfigurationChanged. // to WindowProviderService to make it compatible with Service#onConfigurationChanged.
// Service always receives #onConfigurationChanged callback regardless of display state. // Service always receives #onConfigurationChanged callback regardless of display state.
if (!isWindowProviderService(mOptions) if (!isWindowProviderService(mOptions) && isSuspendedState(dc.getDisplayInfo().state)) {
&& isSuspendedState(mContainer.getDisplayContent().getDisplayInfo().state)) {
mHasPendingConfiguration = true; mHasPendingConfiguration = true;
return; return;
} }
final Configuration config = mContainer.getConfiguration(); final Configuration config = mContainer.getConfiguration();
final int displayId = mContainer.getDisplayContent().getDisplayId(); final int displayId = dc.getDisplayId();
if (mLastReportedConfig == null) { if (mLastReportedConfig == null) {
mLastReportedConfig = new Configuration(); mLastReportedConfig = new Configuration();
} }
@@ -282,9 +287,8 @@ class WindowContextListenerController {
mLastReportedConfig.setTo(config); mLastReportedConfig.setTo(config);
mLastReportedDisplay = displayId; mLastReportedDisplay = displayId;
IWindowToken windowTokenClient = IWindowToken.Stub.asInterface(mClientToken);
try { try {
windowTokenClient.onConfigurationChanged(config, displayId); mClientToken.onConfigurationChanged(config, displayId);
} catch (RemoteException e) { } catch (RemoteException e) {
ProtoLog.w(WM_ERROR, "Could not report config changes to the window token client."); ProtoLog.w(WM_ERROR, "Could not report config changes to the window token client.");
} }
@@ -294,7 +298,7 @@ class WindowContextListenerController {
@Override @Override
public void onRemoved() { public void onRemoved() {
if (mDeathRecipient == null) { if (mDeathRecipient == null) {
throw new IllegalStateException("Invalid client token: " + mClientToken); throw new IllegalStateException("Invalid client token: " + mClientToken.asBinder());
} }
final WindowToken windowToken = mContainer.asWindowToken(); final WindowToken windowToken = mContainer.asWindowToken();
if (windowToken != null && windowToken.isFromClient()) { if (windowToken != null && windowToken.isFromClient()) {
@@ -312,9 +316,8 @@ class WindowContextListenerController {
} }
} }
mDeathRecipient.unlinkToDeath(); mDeathRecipient.unlinkToDeath();
IWindowToken windowTokenClient = IWindowToken.Stub.asInterface(mClientToken);
try { try {
windowTokenClient.onWindowTokenRemoved(); mClientToken.onWindowTokenRemoved();
} catch (RemoteException e) { } catch (RemoteException e) {
ProtoLog.w(WM_ERROR, "Could not report token removal to the window token client."); ProtoLog.w(WM_ERROR, "Could not report token removal to the window token client.");
} }
@@ -323,7 +326,7 @@ class WindowContextListenerController {
@Override @Override
public String toString() { public String toString() {
return "WindowContextListenerImpl{clientToken=" + mClientToken + ", " return "WindowContextListenerImpl{clientToken=" + mClientToken.asBinder() + ", "
+ "container=" + mContainer + "}"; + "container=" + mContainer + "}";
} }
@@ -337,11 +340,11 @@ class WindowContextListenerController {
} }
void linkToDeath() throws RemoteException { void linkToDeath() throws RemoteException {
mClientToken.linkToDeath(this, 0); mClientToken.asBinder().linkToDeath(this, 0);
} }
void unlinkToDeath() { void unlinkToDeath() {
mClientToken.unlinkToDeath(this, 0); mClientToken.asBinder().unlinkToDeath(this, 0);
} }
} }
} }