diff options
| author | 2013-05-31 14:39:48 -0700 | |
|---|---|---|
| committer | 2013-05-31 15:00:24 -0700 | |
| commit | 04fe6ebb9f919f196ec06a19bebc09b8e943f95b (patch) | |
| tree | c6b80f3a8d5ff34227de7b97395883139787ef38 | |
| parent | c1e0ca9fee17cb56a992ae107d3b1aa534290b2d (diff) | |
Fix a bug resolving the correct icon/logo in action bars
Remove some abstraction-breaking magic in ActionBarView and replace it
with proper resolution of the icon/logo when creating a window. The
old implementation relied on the ActionBarView's context being an
Activity.
Bug 9171554
Change-Id: Idbbb1942622195dcb55e8119f2d64287b07bb509
| -rw-r--r-- | api/current.txt | 3 | ||||
| -rw-r--r-- | core/java/android/app/Activity.java | 5 | ||||
| -rw-r--r-- | core/java/android/app/Dialog.java | 5 | ||||
| -rw-r--r-- | core/java/android/content/pm/ComponentInfo.java | 11 | ||||
| -rw-r--r-- | core/java/android/view/IWindowManager.aidl | 2 | ||||
| -rw-r--r-- | core/java/android/view/Window.java | 34 | ||||
| -rw-r--r-- | core/java/android/view/WindowManagerPolicy.java | 2 | ||||
| -rw-r--r-- | core/java/com/android/internal/app/ActionBarImpl.java | 8 | ||||
| -rw-r--r-- | core/java/com/android/internal/widget/ActionBarView.java | 60 | ||||
| -rw-r--r-- | policy/src/com/android/internal/policy/impl/PhoneWindow.java | 55 | ||||
| -rw-r--r-- | policy/src/com/android/internal/policy/impl/PhoneWindowManager.java | 5 | ||||
| -rw-r--r-- | services/java/com/android/server/am/ActivityRecord.java | 2 | ||||
| -rw-r--r-- | services/java/com/android/server/am/ActivityStack.java | 8 | ||||
| -rw-r--r-- | services/java/com/android/server/wm/StartingData.java | 4 | ||||
| -rw-r--r-- | services/java/com/android/server/wm/WindowManagerService.java | 6 | ||||
| -rw-r--r-- | tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java | 2 |
16 files changed, 158 insertions, 54 deletions
diff --git a/api/current.txt b/api/current.txt index f792bcda8cc4..0e217039ffaa 100644 --- a/api/current.txt +++ b/api/current.txt @@ -6808,6 +6808,7 @@ package android.content.pm { ctor public ComponentInfo(android.content.pm.ComponentInfo); ctor protected ComponentInfo(android.os.Parcel); method public final int getIconResource(); + method public final int getLogoResource(); method public boolean isEnabled(); field public android.content.pm.ApplicationInfo applicationInfo; field public int descriptionRes; @@ -27040,7 +27041,9 @@ package android.view { method public void setFlags(int, int); method public void setFormat(int); method public void setGravity(int); + method public void setIcon(int); method public void setLayout(int, int); + method public void setLogo(int); method public void setSoftInputMode(int); method public abstract void setTitle(java.lang.CharSequence); method public abstract void setTitleColor(int); diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 6b5df7f74c70..7f2f74479295 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -1877,9 +1877,12 @@ public class Activity extends ContextThemeWrapper if (isChild() || !window.hasFeature(Window.FEATURE_ACTION_BAR) || mActionBar != null) { return; } - + mActionBar = new ActionBarImpl(this); mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp); + + mWindow.setDefaultIcon(mActivityInfo.getIconResource()); + mWindow.setDefaultLogo(mActivityInfo.getLogoResource()); } /** diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java index b3d99c5242f0..634fa30c1c40 100644 --- a/core/java/android/app/Dialog.java +++ b/core/java/android/app/Dialog.java @@ -16,6 +16,8 @@ package android.app; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import com.android.internal.app.ActionBarImpl; import com.android.internal.policy.PolicyManager; @@ -264,6 +266,9 @@ public class Dialog implements DialogInterface, Window.Callback, mDecor = mWindow.getDecorView(); if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) { + final ApplicationInfo info = mContext.getApplicationInfo(); + mWindow.setDefaultIcon(info.icon); + mWindow.setDefaultLogo(info.logo); mActionBar = new ActionBarImpl(this); } diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java index 28124775fb95..4dbcf233dd33 100644 --- a/core/java/android/content/pm/ComponentInfo.java +++ b/core/java/android/content/pm/ComponentInfo.java @@ -116,6 +116,17 @@ public class ComponentInfo extends PackageItemInfo { public final int getIconResource() { return icon != 0 ? icon : applicationInfo.icon; } + + /** + * Return the logo resource identifier to use for this component. If + * the component defines a logo, that is used; else, the application + * logo is used. + * + * @return The logo associated with this component. + */ + public final int getLogoResource() { + return logo != 0 ? logo : applicationInfo.logo; + } protected void dumpFront(Printer pw, String prefix) { super.dumpFront(pw, prefix); diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 8007d9af9979..ad3082e1f5e2 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -97,7 +97,7 @@ interface IWindowManager void executeAppTransition(); void setAppStartingWindow(IBinder token, String pkg, int theme, in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, - int icon, int windowFlags, IBinder transferFrom, boolean createIfNeeded); + int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded); void setAppWillBeHidden(IBinder token); void setAppVisibility(IBinder token, boolean visible); void startAppFreezingScreen(IBinder token, int configChanges); diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 06974d31e86e..39d48a7d8de3 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -1256,4 +1256,38 @@ public abstract class Window { * @param mask Flags specifying which options should be modified. Others will remain unchanged. */ public void setUiOptions(int uiOptions, int mask) { } + + /** + * Set the primary icon for this window. + * + * @param resId resource ID of a drawable to set + */ + public void setIcon(int resId) { } + + /** + * Set the default icon for this window. + * This will be overridden by any other icon set operation which could come from the + * theme or another explicit set. + * + * @hide + */ + public void setDefaultIcon(int resId) { } + + /** + * Set the logo for this window. A logo is often shown in place of an + * {@link #setIcon(int) icon} but is generally wider and communicates window title information + * as well. + * + * @param resId resource ID of a drawable to set + */ + public void setLogo(int resId) { } + + /** + * Set the default logo for this window. + * This will be overridden by any other logo set operation which could come from the + * theme or another explicit set. + * + * @hide + */ + public void setDefaultLogo(int resId) { } } diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 6a35f20ef53f..6291e628698e 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -642,7 +642,7 @@ public interface WindowManagerPolicy { */ public View addStartingWindow(IBinder appToken, String packageName, int theme, CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, - int labelRes, int icon, int windowFlags); + int labelRes, int icon, int logo, int windowFlags); /** * Called when the first window of an application has been displayed, while diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java index acbb2b145927..e092fffd3bc7 100644 --- a/core/java/com/android/internal/app/ActionBarImpl.java +++ b/core/java/com/android/internal/app/ActionBarImpl.java @@ -1210,6 +1210,10 @@ public class ActionBarImpl extends ActionBar { mActionView.setIcon(icon); } + public boolean hasIcon() { + return mActionView.hasIcon(); + } + @Override public void setLogo(int resId) { mActionView.setLogo(resId); @@ -1220,6 +1224,10 @@ public class ActionBarImpl extends ActionBar { mActionView.setLogo(logo); } + public boolean hasLogo() { + return mActionView.hasLogo(); + } + public void setDefaultDisplayHomeAsUpEnabled(boolean enable) { if (!mDisplayHomeAsUpSet) { setDisplayHomeAsUpEnabled(enable); diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index dda1a105d76c..f2bd5224ffcf 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -16,24 +16,12 @@ package com.android.internal.widget; -import com.android.internal.R; -import com.android.internal.view.menu.ActionMenuItem; -import com.android.internal.view.menu.ActionMenuPresenter; -import com.android.internal.view.menu.ActionMenuView; -import com.android.internal.view.menu.MenuBuilder; -import com.android.internal.view.menu.MenuItemImpl; -import com.android.internal.view.menu.MenuPresenter; -import com.android.internal.view.menu.MenuView; -import com.android.internal.view.menu.SubMenuBuilder; - import android.animation.LayoutTransition; import android.app.ActionBar; import android.app.ActionBar.OnNavigationListener; -import android.app.Activity; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; @@ -42,7 +30,6 @@ import android.os.Parcelable; import android.text.Layout; import android.text.TextUtils; import android.util.AttributeSet; -import android.util.Log; import android.view.CollapsibleActionView; import android.view.Gravity; import android.view.LayoutInflater; @@ -62,6 +49,15 @@ import android.widget.ProgressBar; import android.widget.Spinner; import android.widget.SpinnerAdapter; import android.widget.TextView; +import com.android.internal.R; +import com.android.internal.view.menu.ActionMenuItem; +import com.android.internal.view.menu.ActionMenuPresenter; +import com.android.internal.view.menu.ActionMenuView; +import com.android.internal.view.menu.MenuBuilder; +import com.android.internal.view.menu.MenuItemImpl; +import com.android.internal.view.menu.MenuPresenter; +import com.android.internal.view.menu.MenuView; +import com.android.internal.view.menu.SubMenuBuilder; /** * @hide @@ -188,34 +184,8 @@ public class ActionBarView extends AbsActionBarView { ActionBar.NAVIGATION_MODE_STANDARD); mTitle = a.getText(R.styleable.ActionBar_title); mSubtitle = a.getText(R.styleable.ActionBar_subtitle); - mLogo = a.getDrawable(R.styleable.ActionBar_logo); - if (mLogo == null) { - if (context instanceof Activity) { - try { - mLogo = pm.getActivityLogo(((Activity) context).getComponentName()); - } catch (NameNotFoundException e) { - Log.e(TAG, "Activity component name not found!", e); - } - } - if (mLogo == null) { - mLogo = appInfo.loadLogo(pm); - } - } - mIcon = a.getDrawable(R.styleable.ActionBar_icon); - if (mIcon == null) { - if (context instanceof Activity) { - try { - mIcon = pm.getActivityIcon(((Activity) context).getComponentName()); - } catch (NameNotFoundException e) { - Log.e(TAG, "Activity component name not found!", e); - } - } - if (mIcon == null) { - mIcon = appInfo.loadIcon(pm); - } - } final LayoutInflater inflater = LayoutInflater.from(context); @@ -729,7 +699,11 @@ public class ActionBarView extends AbsActionBarView { } public void setIcon(int resId) { - setIcon(mContext.getResources().getDrawable(resId)); + setIcon(resId != 0 ? mContext.getResources().getDrawable(resId) : null); + } + + public boolean hasIcon() { + return mIcon != null; } public void setLogo(Drawable logo) { @@ -740,7 +714,11 @@ public class ActionBarView extends AbsActionBarView { } public void setLogo(int resId) { - setLogo(mContext.getResources().getDrawable(resId)); + setLogo(resId != 0 ? mContext.getResources().getDrawable(resId) : null); + } + + public boolean hasLogo() { + return mLogo != null; } public void setNavigationMode(int mode) { diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index 6b28e8e68777..085134d412ef 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -139,6 +139,12 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private ActionMenuPresenterCallback mActionMenuPresenterCallback; private PanelMenuPresenterCallback mPanelMenuPresenterCallback; + static final int FLAG_RESOURCE_SET_ICON = 1 << 0; + static final int FLAG_RESOURCE_SET_LOGO = 1 << 1; + int mResourcesSetFlags; + int mIconRes; + int mLogoRes; + private DrawableFeatureState[] mDrawables; private PanelFeatureState[] mPanels; @@ -1393,6 +1399,46 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } } + @Override + public void setIcon(int resId) { + mIconRes = resId; + mResourcesSetFlags |= FLAG_RESOURCE_SET_ICON; + if (mActionBar != null) { + mActionBar.setIcon(resId); + } + } + + @Override + public void setDefaultIcon(int resId) { + if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) != 0) { + return; + } + mIconRes = resId; + if (mActionBar != null && !mActionBar.hasIcon()) { + mActionBar.setIcon(resId); + } + } + + @Override + public void setLogo(int resId) { + mLogoRes = resId; + mResourcesSetFlags |= FLAG_RESOURCE_SET_LOGO; + if (mActionBar != null) { + mActionBar.setLogo(resId); + } + } + + @Override + public void setDefaultLogo(int resId) { + if ((mResourcesSetFlags & FLAG_RESOURCE_SET_LOGO) != 0) { + return; + } + mLogoRes = resId; + if (mActionBar != null && !mActionBar.hasLogo()) { + mActionBar.setLogo(resId); + } + } + /** * Request that key events come to this activity. Use this if your activity * has no views with focus, but the activity still wants a chance to process @@ -2946,6 +2992,15 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { "incompatible window decor! Ignoring request."); } + if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) != 0 || + (mIconRes != 0 && !mActionBar.hasIcon())) { + mActionBar.setIcon(mIconRes); + } + if ((mResourcesSetFlags & FLAG_RESOURCE_SET_LOGO) != 0 || + (mLogoRes != 0 && !mActionBar.hasLogo())) { + mActionBar.setLogo(mLogoRes); + } + // Post the panel invalidate for later; avoid application onCreateOptionsMenu // being called in the middle of onCreate or similar. mDecor.post(new Runnable() { diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 79753a68e1f5..b8a9797ae59e 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -1582,7 +1582,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { @Override public View addStartingWindow(IBinder appToken, String packageName, int theme, CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, - int icon, int windowFlags) { + int icon, int logo, int windowFlags) { if (!SHOW_STARTING_ANIMATIONS) { return null; } @@ -1639,6 +1639,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { win.addFlags(WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW); } + win.setDefaultIcon(icon); + win.setDefaultLogo(logo); + win.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index a40b13c5c85e..561dd0f2d3f2 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -86,6 +86,7 @@ final class ActivityRecord { CharSequence nonLocalizedLabel; // the label information from the package mgr. int labelRes; // the label information from the package mgr. int icon; // resource identifier of activity's icon. + int logo; // resource identifier of activity's logo. int theme; // resource identifier of activity's theme. int realTheme; // actual theme resource we will use, never 0. int windowFlags; // custom window flags for preview window. @@ -399,6 +400,7 @@ final class ActivityRecord { labelRes = app.labelRes; } icon = aInfo.getIconResource(); + logo = aInfo.getLogoResource(); theme = aInfo.getThemeResource(); realTheme = theme; if (realTheme == 0) { diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index d6a6eb8b4e97..50ed21bf057b 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -1465,8 +1465,8 @@ final class ActivityStack { mWindowManager.setAppStartingWindow( next.appToken, next.packageName, next.theme, mService.compatibilityInfoForPackageLocked(next.info.applicationInfo), - next.nonLocalizedLabel, next.labelRes, next.icon, next.windowFlags, - null, true); + next.nonLocalizedLabel, next.labelRes, next.icon, next.logo, + next.windowFlags, null, true); } mStackSupervisor.startSpecificActivityLocked(next, true, false); if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); @@ -1500,7 +1500,7 @@ final class ActivityStack { mService.compatibilityInfoForPackageLocked( next.info.applicationInfo), next.nonLocalizedLabel, - next.labelRes, next.icon, next.windowFlags, + next.labelRes, next.icon, next.logo, next.windowFlags, null, true); } if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next); @@ -1639,7 +1639,7 @@ final class ActivityStack { r.appToken, r.packageName, r.theme, mService.compatibilityInfoForPackageLocked( r.info.applicationInfo), r.nonLocalizedLabel, - r.labelRes, r.icon, r.windowFlags, + r.labelRes, r.icon, r.logo, r.windowFlags, prev != null ? prev.appToken : null, showStartingIcon); } } else { diff --git a/services/java/com/android/server/wm/StartingData.java b/services/java/com/android/server/wm/StartingData.java index 46bb480a08dd..7115b0fd02e5 100644 --- a/services/java/com/android/server/wm/StartingData.java +++ b/services/java/com/android/server/wm/StartingData.java @@ -25,17 +25,19 @@ final class StartingData { final CharSequence nonLocalizedLabel; final int labelRes; final int icon; + final int logo; final int windowFlags; StartingData(String _pkg, int _theme, CompatibilityInfo _compatInfo, CharSequence _nonLocalizedLabel, - int _labelRes, int _icon, int _windowFlags) { + int _labelRes, int _icon, int _logo, int _windowFlags) { pkg = _pkg; theme = _theme; compatInfo = _compatInfo; nonLocalizedLabel = _nonLocalizedLabel; labelRes = _labelRes; icon = _icon; + logo = _logo; windowFlags = _windowFlags; } }
\ No newline at end of file diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index a1e07dc9982c..b4dcdec18bdc 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -3878,7 +3878,7 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void setAppStartingWindow(IBinder token, String pkg, int theme, CompatibilityInfo compatInfo, - CharSequence nonLocalizedLabel, int labelRes, int icon, + CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "setAppStartingWindow()")) { @@ -4079,7 +4079,7 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData"); mStartingIconInTransition = true; wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel, - labelRes, icon, windowFlags); + labelRes, icon, logo, windowFlags); Message m = mH.obtainMessage(H.ADD_STARTING, wtoken); // Note: we really want to do sendMessageAtFrontOfQueue() because we // want to process the message ASAP, before any other queued @@ -7083,7 +7083,7 @@ public class WindowManagerService extends IWindowManager.Stub try { view = mPolicy.addStartingWindow( wtoken.token, sd.pkg, sd.theme, sd.compatInfo, - sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.windowFlags); + sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.logo, sd.windowFlags); } catch (Exception e) { Slog.w(TAG, "Exception when adding starting window", e); } diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java index 0ca230c46e96..a7b48bb1c859 100644 --- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java @@ -304,7 +304,7 @@ public class IWindowManagerImpl implements IWindowManager { @Override public void setAppStartingWindow(IBinder arg0, String arg1, int arg2, CompatibilityInfo arg3, - CharSequence arg4, int arg5, int arg6, int arg7, IBinder arg8, boolean arg9) + CharSequence arg4, int arg5, int arg6, int arg7, int arg8, IBinder arg9, boolean arg10) throws RemoteException { // TODO Auto-generated method stub } |