Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4dc0c15a authored by Vadim Tryshev's avatar Vadim Tryshev
Browse files

Making sure that after a rotation Shelf shows latest set of pinned apps.

2 copies of NavigationBarApps (for vertical and for horizontal orientation) share a single
static copy of NavigationBarsAppsModel.
If the active orientation's view made changes, they are not conveyed
to the inactive one, and if we rotate to show the other view, it will show
stale data.

The fix introduces an event generated by the model, which allows the invisible
shelf to get updated when the visible one makes changes.

Bug: 20024603
Change-Id: I0d749dbac700857b081bce8a5a232f24ba271b25
parent 27c8b2c2
Loading
Loading
Loading
Loading
+28 −12
Original line number Diff line number Diff line
@@ -69,7 +69,8 @@ import java.util.List;
 * Navigation bar contains both pinned and unpinned apps: pinned in the left part, unpinned in the
 * right part, with no separator in between.
 */
class NavigationBarApps extends LinearLayout {
class NavigationBarApps extends LinearLayout
        implements NavigationBarAppsModel.OnAppsChangedListener {
    public final static boolean DEBUG = false;
    private final static String TAG = "NavigationBarApps";

@@ -131,7 +132,9 @@ class NavigationBarApps extends LinearLayout {

    public NavigationBarApps(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (sAppsModel == null) {
            sAppsModel = new NavigationBarAppsModel(context);
        }
        mPackageManager = context.getPackageManager();
        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
@@ -285,6 +288,7 @@ class NavigationBarApps extends LinearLayout {
        mContext.registerReceiver(mBroadcastReceiver, filter);

        mAppPackageMonitor.register(mContext, null, UserHandle.ALL, true);
        sAppsModel.addOnAppsChangedListener(this);
    }

    @Override
@@ -292,6 +296,7 @@ class NavigationBarApps extends LinearLayout {
        super.onDetachedFromWindow();
        mContext.unregisterReceiver(mBroadcastReceiver);
        mAppPackageMonitor.unregister();
        sAppsModel.removeOnAppsChangedListener(this);
    }

    @Override
@@ -315,6 +320,19 @@ class NavigationBarApps extends LinearLayout {
        new GetActivityIconTask(mPackageManager, button).execute(appButtonData);
    }

    private List<AppInfo> getPinnedApps() {
        List<AppInfo> apps = new ArrayList<AppInfo>();
        int childCount = getChildCount();
        for (int i = 0; i != childCount; ++i) {
            View child = getChildAt(i);
            AppButtonData appButtonData = (AppButtonData)child.getTag();
            if (appButtonData == null) continue;  // Skip the drag placeholder.
            if(!appButtonData.pinned) continue;
            apps.add(appButtonData.appInfo);
        }
        return apps;
    }

    /**
     * Creates an ImageView icon for each pinned app. Removes any existing icons. May be called
     * to synchronize the current view with the shared data mode.
@@ -335,16 +353,7 @@ class NavigationBarApps extends LinearLayout {
     * Saves pinned apps stored in app icons into the data model.
     */
    private void savePinnedApps() {
        List<AppInfo> apps = new ArrayList<AppInfo>();
        int childCount = getChildCount();
        for (int i = 0; i != childCount; ++i) {
            View child = getChildAt(i);
            AppButtonData appButtonData = (AppButtonData)child.getTag();
            if (appButtonData == null) continue;  // Skip the drag placeholder.
            if(!appButtonData.pinned) continue;
            apps.add(appButtonData.appInfo);
        }
        sAppsModel.setApps(apps);
        sAppsModel.setApps(getPinnedApps());
    }

    /**
@@ -1102,4 +1111,11 @@ class NavigationBarApps extends LinearLayout {
            });
        }
    }

    @Override
    public void onPinnedAppsChanged() {
        if (getPinnedApps().equals(sAppsModel.getApps())) return;
        recreatePinnedAppButtons();
        updateRecentApps();
    }
}
+20 −0
Original line number Diff line number Diff line
@@ -44,6 +44,10 @@ import java.util.Set;
 * ComponentName.
 */
class NavigationBarAppsModel {
    public interface OnAppsChangedListener {
        void onPinnedAppsChanged();
    }

    private final static String TAG = "NavigationBarAppsModel";

    // Default number of apps to load initially.
@@ -79,6 +83,9 @@ class NavigationBarAppsModel {
    // Apps are represented as an ordered list of app infos.
    private List<AppInfo> mApps = new ArrayList<AppInfo>();

    private List<OnAppsChangedListener> mOnAppsChangedListeners =
            new ArrayList<OnAppsChangedListener>();

    // Id of the current user.
    private int mCurrentUserId = -1;

@@ -167,6 +174,14 @@ class NavigationBarAppsModel {
        return null;
    }

    public void addOnAppsChangedListener(OnAppsChangedListener listener) {
        mOnAppsChangedListeners.add(listener);
    }

    public void removeOnAppsChangedListener(OnAppsChangedListener listener) {
        mOnAppsChangedListeners.remove(listener);
    }

    /**
     * Reinitializes the model for a new user.
     */
@@ -239,6 +254,11 @@ class NavigationBarAppsModel {
    public void setApps(List<AppInfo> apps) {
        mApps = apps;
        savePrefs();

        int size = mOnAppsChangedListeners.size();
        for (int i = 0; i < size; ++i) {
            mOnAppsChangedListeners.get(i).onPinnedAppsChanged();
        }
    }

    /** Saves the current model to disk. */
+15 −0
Original line number Diff line number Diff line
@@ -412,4 +412,19 @@ public class NavigationBarAppsModelTest extends AndroidTestCase {
        verify(mMockEdit).apply();
        verifyNoMoreInteractions(mMockEdit);
    }

    /** Tests the apps-changed listener. */
    public void testAppsChangedListeners() {
        NavigationBarAppsModel.OnAppsChangedListener listener =
                mock(NavigationBarAppsModel.OnAppsChangedListener.class);

        mModel.addOnAppsChangedListener(listener);
        mModel.setApps(new ArrayList<AppInfo>());
        verify(listener).onPinnedAppsChanged();
        verifyNoMoreInteractions(listener);

        mModel.removeOnAppsChangedListener(listener);
        mModel.setApps(new ArrayList<AppInfo>());
        verifyNoMoreInteractions(listener);
    }
}