Activity starting window and how to speed up activity starting (Android 7.0)

A starting preview window is shown during activity starting. The feature is implemented in ActivityStack.startActivityLocked method.


Inframeworks/base/services/core/java/com/android/server/am/ActivityStack.java

2690    final void startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition,
2691            ActivityOptions options) {
...............................
2756        if (!isHomeStack() || numActivities() > 0) {
2757            // We want to show the starting preview window if we are
2758            // switching to a new task, or the next activity's process is
2759            // not currently running.
...................................
2797            if (r.mLaunchTaskBehind) {
2798                // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
2799                // tell WindowManager that r is visible even though it is at the back of the stack.
2800                mWindowManager.setAppVisibility(r.appToken, true);
2801                ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
2802            } else if (SHOW_APP_STARTING_PREVIEW && doShow) {     //  SHOW_APP_STARTING_PREVIEW is true by default
2803                // Figure out if we are transitioning from another activity that is
2804                // "has the same starting icon" as the next one.  This allows the
2805                // window manager to keep the previous window it had previously
2806                // created, if it still had one.
2807                ActivityRecord prev = r.task.topRunningActivityWithStartingWindowLocked();
2808                if (prev != null) {
2809                    // We don't want to reuse the previous starting preview if:
2810                    // (1) The current activity is in a different task.
2811                    if (prev.task != r.task) {
2812                        prev = null;
2813                    }
2814                    // (2) The current activity is already displayed.
2815                    else if (prev.nowVisible) {
2816                        prev = null;
2817                    }
2818                }
2819                r.showStartingWindow(prev, showStartingIcon);
2820                VendorActivityStackCallback.callOnAppStartingPreview(mVendorCallbacks, r.intent, mService.mContext);
2821            }
.........................
2832    }


Inframeworks/base/services/core/java/com/android/server/am/ActivityRecord.java

1418    void showStartingWindow(ActivityRecord prev, boolean createIfNeeded) {
1419        final CompatibilityInfo compatInfo =
1420                service.compatibilityInfoForPackageLocked(info.applicationInfo);
1421        final boolean shown = service.mWindowManager.setAppStartingWindow(
1422                appToken, packageName, theme, compatInfo, nonLocalizedLabel, labelRes, icon,
1423                logo, windowFlags, prev != null ? prev.appToken : null, createIfNeeded);
1424        if (shown) {
1425            mStartingWindowState = STARTING_WINDOW_SHOWN;
1426        }
1427    }


Inframeworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

4201    public boolean setAppStartingWindow(IBinder token, String pkg,
4202            int theme, CompatibilityInfo compatInfo,
4203            CharSequence nonLocalizedLabel, int labelRes, int icon, int logo,
4204            int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
4209
4210        synchronized(mWindowMap) {
.................................
4231
4232            // If this is a translucent window, then don't
4233            // show a starting window -- the current effect (a full-screen
4234            // opaque starting window that fades away to the real contents
4235            // when it is ready) does not work for this.
4238            if (theme != 0) {
4239                AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
4240                        com.android.internal.R.styleable.Window, mCurrentUserId);
4241                if (ent == null) {
4242                    // Whoops!  App doesn't exist.  Um.  Okay.  We'll just
4243                    // pretend like we didn't see that.
4244                    return false;
4245                }
4246                final boolean windowIsTranslucent = ent.array.getBoolean(
4247                        com.android.internal.R.styleable.Window_windowIsTranslucent, false);
4248                final boolean windowIsFloating = ent.array.getBoolean(
4249                        com.android.internal.R.styleable.Window_windowIsFloating, false);
4250                final boolean windowShowWallpaper = ent.array.getBoolean(
4251                        com.android.internal.R.styleable.Window_windowShowWallpaper, false);
4252                final boolean windowDisableStarting = ent.array.getBoolean(
4253                        com.android.internal.R.styleable.Window_windowDisablePreview, false);
4254                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Translucent=" + windowIsTranslucent
4255                        + " Floating=" + windowIsFloating
4256                        + " ShowWallpaper=" + windowShowWallpaper);
4257                if (windowIsTranslucent) {
4258                    return false;
4259                }
4260                if (windowIsFloating || windowDisableStarting) {
4261                    return false;
4262                }
4263                if (windowShowWallpaper) {
4264                    if (mWallpaperControllerLocked.getWallpaperTarget() == null) {
4265                        // If this theme is requesting a wallpaper, and the wallpaper
4266                        // is not currently visible, then this effectively serves as
4267                        // an opaque window and our starting window transition animation
4268                        // can still work.  We just need to make sure the starting window
4269                        // is also showing the wallpaper.
4270                        windowFlags |= FLAG_SHOW_WALLPAPER;
4271                    } else {
4272                        return false;
4273                    }
4274                }
4275            }
...........................
4287            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating StartingData");
4288            wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
4289                    labelRes, icon, logo, windowFlags);
4290            Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4291            // Note: we really want to do sendMessageAtFrontOfQueue() because we
4292            // want to process the message ASAP, before any other queued
4293            // messages.
4295            mH.sendMessageAtFrontOfQueue(m);
4296        }
4297        return true;
4298    }

8382                case ADD_STARTING: {
8395                    try {
8396                        final Configuration overrideConfig = wtoken != null && wtoken.mTask != null
8397                                ? wtoken.mTask.mOverrideConfig : null;
8398                        view = mPolicy.addStartingWindow(wtoken.token, sd.pkg, sd.theme,
8399                            sd.compatInfo, sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.logo,
8400                            sd.windowFlags, overrideConfig);
8401                    } catch (Exception e) {
8402                        Slog.w(TAG_WM, "Exception when adding starting window", e);
8403                    }
8404
8439                } break;


In frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

static final boolean SHOW_STARTING_ANIMATIONS = true;  // decide if we need show starting window

2190    public View addStartingWindow(IBinder appToken, String packageName, int theme,
2191            CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
2192            int icon, int logo, int windowFlags) {
// we can add a callback function here to skip adding starting window to WM
2193        if (!SHOW_STARTING_ANIMATIONS || VendorPhoneWindowManagerCallback.callSkipAddStartingWindow(mVendorCallbacks)) { 
2194            return null;
2195        }
2202
2203        try {
...........................
2217            Window win = PolicyManager.makeNewWindow(context);
2218            final TypedArray ta = win.getWindowStyle();
2219
2220            // performance_improve begin, skip starting window of some application to optimize performance.
2221            if (!packageName.equals(FIRE_LAUNCHER_PACKAGE) && (
2222                    ta.getBoolean(
2223                            com.android.internal.R.styleable.Window_windowDisablePreview, false)
2224                    || ta.getBoolean(
2225                            com.android.internal.R.styleable.Window_windowShowWallpaper,false))
2226                ) {
2227                return null;
2228            }
2229            // performance_improve end
2230
2231            Resources r = context.getResources();
2232            win.setTitle(r.getText(labelRes, nonLocalizedLabel));
2233
2234            win.setType(
2235                WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
2236            // Force the window flags: this is a fake window, so it is not really
2237            // touchable or focusable by the user.  We also add in the ALT_FOCUSABLE_IM
2238            // flag because we do know that the next window will take input
2239            // focus, so we want to get the IME window up on top of us right away.
2240            win.setFlags(
2241                windowFlags|
2242                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
2243                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
2244                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
2245                windowFlags|
2246                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
2247                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
2248                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
2249
2250            win.setDefaultIcon(icon);
2251            win.setDefaultLogo(logo);
2252
2253            win.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
2254                    WindowManager.LayoutParams.MATCH_PARENT);
2255
2256            final WindowManager.LayoutParams params = win.getAttributes();
2257            params.token = appToken;
2258            params.packageName = packageName;
2259            params.windowAnimations = win.getWindowStyle().getResourceId(
2260                    com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
2261            params.privateFlags |=
2262                    WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED;
2263            params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
2264
2265            if (!compatInfo.supportsScreen()) {
2266                params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
2267            }
2268
2269            params.setTitle("Starting " + packageName);
2270
2271            wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
2272            view = win.getDecorView();
2273
2274            if (win.isFloating()) {
2275                // Whoops, there is no way to display an animation/preview
2276                // of such a thing!  After all that work...  let's skip it.
2277                // (Note that we must do this here because it is in
2278                // getDecorView() where the theme is evaluated...  maybe
2279                // we should peek the floating attribute from the theme
2280                // earlier.)
2281                return null;
2282            }
2283
2288
2289            // fosmod_vendor_callbacks begin
2290            Rect contentRect;
2291            if ((windowFlags & FLAG_FULLSCREEN) != 0) {
2292                contentRect = new Rect(mStableFullscreenLeft, mStableFullscreenTop,
2293                    mStableFullscreenRight, mStableFullscreenBottom);
2294            } else {
2295                contentRect = new Rect(mStableLeft, mStableTop,
2296                    mStableRight, mStableBottom);
2297            }
2298            VendorPhoneWindowManagerCallback.callAddCustomStartingWindow(   // a custom callback to add customized starting window instead of original one.
2299                mVendorCallbacks,
2300                view,
2301                context,
2302                packageName,
2303                mOrientationListener.getProposedRotation(),
2304                contentRect,
2305                new Rect(
2306                    mRestrictedScreenLeft,
2307                    mRestrictedScreenTop,
2308                    mRestrictedScreenLeft + mRestrictedScreenWidth,
2309                    mRestrictedScreenTop + mRestrictedOverscanScreenHeight
2310                )
2311            );
2312            // fosmod_vendor_callbacks end
2313
2314            wm.addView(view, params);
2315
2316            // Only return the view if it was successfully added to the
2317            // window manager... which we can tell by it having a parent.
2318            return view.getParent() != null ? view : null;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值