diff options
| author | Charles Chen <charlesccchen@google.com> | 2020-09-02 17:21:11 +0800 |
|---|---|---|
| committer | Charles Chen <charlesccchen@google.com> | 2021-03-24 11:26:50 +0800 |
| commit | f48ece487503bee929ffb4dae9e9c82e89c659d2 (patch) | |
| tree | 9098dc44d467f602e41e2369a8810d23df123c19 /core/java/android/window/WindowTokenClient.java | |
| parent | ad97628537b08097183318c580dfcce1ad98b746 (diff) | |
Move WindowContext module to window package
In this way, we can clarify the owners and it is easier to maintain.
Also refactor to move WindowContext creation logic to ContextImpl.
Test: atest WindowContext WindowContextTests WindowContextPolicyTests
Bug: 159767464
Bug: 152193787
Change-Id: I78432aa18aa97e001f5a9a04321109e456fd137b
Diffstat (limited to 'core/java/android/window/WindowTokenClient.java')
| -rw-r--r-- | core/java/android/window/WindowTokenClient.java | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/core/java/android/window/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java new file mode 100644 index 000000000000..b2fe4d9573f1 --- /dev/null +++ b/core/java/android/window/WindowTokenClient.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2020 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.window; + +import android.annotation.NonNull; +import android.app.ActivityThread; +import android.app.IWindowToken; +import android.app.ResourcesManager; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.IBinder; +import android.view.WindowManagerGlobal; + +import java.lang.ref.WeakReference; + +/** + * This class is used to receive {@link Configuration} changes from the associated window manager + * node on the server side, and apply the change to the {@link Context#getResources() associated + * Resources} of the attached {@link Context}. It is also used as + * {@link Context#getWindowContextToken() the token of non-Activity UI Contexts}. + * + * @see WindowContext + * @see android.view.IWindowManager#registerWindowContextListener(IBinder, int, int, Bundle) + * + * @hide + */ +public class WindowTokenClient extends IWindowToken.Stub { + /** + * Attached {@link Context} for this window token to update configuration and resources. + * Initialized by {@link #attachContext(Context)}. + */ + private WeakReference<Context> mContextRef = null; + + private final ResourcesManager mResourcesManager = ResourcesManager.getInstance(); + + /** + * Attaches {@code context} to this {@link WindowTokenClient}. Each {@link WindowTokenClient} + * can only attach one {@link Context}. + * <p>This method must be called before invoking + * {@link android.view.IWindowManager#registerWindowContextListener(IBinder, int, int, + * Bundle, boolean)}.<p/> + * + * @param context context to be attached + * @throws IllegalStateException if attached context has already existed. + */ + public void attachContext(@NonNull Context context) { + if (mContextRef != null) { + throw new IllegalStateException("Context is already attached."); + } + mContextRef = new WeakReference<>(context); + } + + @Override + public void onConfigurationChanged(Configuration newConfig, int newDisplayId) { + final Context context = mContextRef.get(); + if (context == null) { + return; + } + final int currentDisplayId = context.getDisplayId(); + final boolean displayChanged = newDisplayId != currentDisplayId; + final Configuration config = context.getResources().getConfiguration(); + final boolean configChanged = config.diff(newConfig) != 0; + if (displayChanged || configChanged) { + // TODO(ag/9789103): update resource manager logic to track non-activity tokens + mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId); + if (context instanceof WindowContext) { + ActivityThread.currentActivityThread().getHandler().post( + () -> ((WindowContext) context).dispatchConfigurationChanged(newConfig)); + } + } + if (displayChanged) { + context.updateDisplay(newDisplayId); + } + } + + @Override + public void onWindowTokenRemoved() { + final Context context = mContextRef.get(); + if (context != null) { + context.destroy(); + mContextRef.clear(); + } + ActivityThread.currentActivityThread().getHandler().post(() -> { + // If the tracked window token is detached, release all views attached to this token. + WindowManagerGlobal.getInstance().closeAll(WindowTokenClient.this, + "#onWindowTokenRemoved()", "WindowTokenClient"); + }); + } +} |
