Added context modes to ActionBar API.

Change-Id: I7c3e782cbf01be7bc671b377fb4d706040888833
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
new file mode 100644
index 0000000..b36524e
--- /dev/null
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2010 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 com.android.internal.app;
+
+import com.android.internal.view.menu.ActionMenu;
+import com.android.internal.view.menu.ActionMenuItem;
+import com.android.internal.widget.ActionBarContextView;
+import com.android.internal.widget.ActionBarView;
+
+import android.app.ActionBar;
+import android.graphics.drawable.Drawable;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.SpinnerAdapter;
+import android.widget.ViewAnimator;
+
+/**
+ * ActionBarImpl is the ActionBar implementation used
+ * by devices of all screen sizes. If it detects a compatible decor,
+ * it will split contextual modes across both the ActionBarView at
+ * the top of the screen and a horizontal LinearLayout at the bottom
+ * which is normally hidden.
+ */
+public class ActionBarImpl extends ActionBar {
+    private static final int NORMAL_VIEW = 0;
+    private static final int CONTEXT_VIEW = 1;
+    
+    private ViewAnimator mAnimatorView;
+    private ActionBarView mActionView;
+    private ActionBarContextView mUpperContextView;
+    private LinearLayout mLowerContextView;
+    
+    private ContextMode mContextMode;
+    
+    private static final int CONTEXT_DISPLAY_NORMAL = 0;
+    private static final int CONTEXT_DISPLAY_SPLIT = 1;
+    
+    private int mContextDisplayMode;
+    
+    public ActionBarImpl(View decor) {
+        mActionView = (ActionBarView) decor.findViewById(com.android.internal.R.id.action_bar);
+        mUpperContextView = (ActionBarContextView) decor.findViewById(
+                com.android.internal.R.id.action_context_bar);
+        mLowerContextView = (LinearLayout) decor.findViewById(
+                com.android.internal.R.id.lower_action_context_bar);
+        mAnimatorView = (ViewAnimator) decor.findViewById(
+                com.android.internal.R.id.action_bar_animator);
+        
+        if (mActionView == null || mUpperContextView == null || mAnimatorView == null) {
+            throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
+                    "with a compatible window decor layout");
+        }
+        
+        mContextDisplayMode = mLowerContextView == null ?
+                CONTEXT_DISPLAY_NORMAL : CONTEXT_DISPLAY_SPLIT;
+    }
+
+    public void setCustomNavigationMode(View view) {
+        mActionView.setCustomNavigationView(view);
+        mActionView.setCallback(null);
+    }
+    
+    public void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback) {
+        mActionView.setCallback(callback);
+        mActionView.setNavigationMode(NAVIGATION_MODE_DROPDOWN_LIST);
+        mActionView.setDropdownAdapter(adapter);
+    }
+    
+    public void setStandardNavigationMode(CharSequence title) {
+        setStandardNavigationMode(title, null);
+    }
+    
+    public void setStandardNavigationMode(CharSequence title, CharSequence subtitle) {
+        mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD);
+        mActionView.setTitle(title);
+        mActionView.setSubtitle(subtitle);
+        mActionView.setCallback(null);
+    }
+
+    public void setDisplayOptions(int options) {
+        mActionView.setDisplayOptions(options);
+    }
+    
+    public void setDisplayOptions(int options, int mask) {
+        final int current = mActionView.getDisplayOptions(); 
+        mActionView.setDisplayOptions((options & mask) | (current & ~mask));
+    }
+
+    public void setBackgroundDrawable(Drawable d) {
+        mActionView.setBackgroundDrawable(d);
+    }
+
+    public View getCustomNavigationView() {
+        return mActionView.getCustomNavigationView();
+    }
+
+    public CharSequence getTitle() {
+        return mActionView.getTitle();
+    }
+
+    public CharSequence getSubtitle() {
+        return mActionView.getSubtitle();
+    }
+
+    public int getNavigationMode() {
+        return mActionView.getNavigationMode();
+    }
+
+    public int getDisplayOptions() {
+        return mActionView.getDisplayOptions();
+    }
+
+    @Override
+    public void startContextMode(ContextModeCallback callback) {
+        if (mContextMode != null) {
+            mContextMode.finish();
+        }
+        mContextMode = new ContextMode(callback);
+        if (callback.onCreateContextMode(mContextMode, mContextMode.getMenu())) {
+            mContextMode.invalidate();
+            mUpperContextView.initForMode(mContextMode);
+            mAnimatorView.setDisplayedChild(CONTEXT_VIEW);
+            if (mLowerContextView != null) {
+                // TODO animate this
+                mLowerContextView.setVisibility(View.VISIBLE);
+            }
+        }
+    }
+
+    @Override
+    public void finishContextMode() {
+        if (mContextMode != null) {
+            mContextMode.finish();
+        }
+    }
+
+    /**
+     * @hide 
+     */
+    public class ContextMode extends ActionBar.ContextMode {
+        private ContextModeCallback mCallback;
+        private ActionMenu mMenu;
+        
+        public ContextMode(ContextModeCallback callback) {
+            mCallback = callback;
+            mMenu = new ActionMenu(mActionView.getContext());
+        }
+        
+        @Override
+        public Menu getMenu() {
+            return mMenu;
+        }
+
+        @Override
+        public void finish() {
+            mCallback.onDestroyContextMode(this);
+            mUpperContextView.closeMode();
+            if (mLowerContextView != null) {
+                mLowerContextView.removeAllViews();
+            }
+            mAnimatorView.setDisplayedChild(NORMAL_VIEW);
+            if (mLowerContextView != null && mLowerContextView.getVisibility() != View.GONE) {
+                // TODO Animate this
+                mLowerContextView.setVisibility(View.GONE);
+            }
+            mContextMode = null;
+        }
+
+        @Override
+        public void invalidate() {
+            if (mCallback.onPrepareContextMode(this, mMenu)) {
+                // Refresh content in both context views
+            }
+        }
+
+        @Override
+        public void setCustomView(View view) {
+            mUpperContextView.setCustomView(view);
+        }
+
+        @Override
+        public void setSubtitle(CharSequence subtitle) {
+            mUpperContextView.setSubtitle(subtitle);
+        }
+
+        @Override
+        public void setTitle(CharSequence title) {
+            mUpperContextView.setTitle(title);
+        }
+        
+        public void dispatchOnContextItemClicked(MenuItem item) {
+            ActionMenuItem actionItem = (ActionMenuItem) item;
+            if (!actionItem.invoke()) {
+                mCallback.onContextItemClicked(this, item);
+            }
+        }
+    }
+}