13954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes/*
23954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * Copyright (C) 2013 The Android Open Source Project
33954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes *
43954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * Licensed under the Apache License, Version 2.0 (the "License");
53954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * you may not use this file except in compliance with the License.
63954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * You may obtain a copy of the License at
73954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes *
83954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes *      http://www.apache.org/licenses/LICENSE-2.0
93954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes *
103954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * Unless required by applicable law or agreed to in writing, software
113954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * distributed under the License is distributed on an "AS IS" BASIS,
123954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * See the License for the specific language governing permissions and
143954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes * limitations under the License.
153954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes */
163954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
173954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banespackage android.support.v7.app;
183954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
19d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banesimport android.content.Context;
203954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.content.pm.ActivityInfo;
213954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.content.pm.PackageManager;
223954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.content.res.Configuration;
235a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banesimport android.content.res.TypedArray;
245a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banesimport android.os.Build;
253954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.os.Bundle;
2645d973fcc4c43f5ea00cddd3d9b947d9e8d8fc4eChris Banesimport android.support.v4.app.ActionBarDrawerToggle;
275a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banesimport android.support.v7.appcompat.R;
285a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banesimport android.support.v7.internal.view.SupportMenuInflater;
29d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banesimport android.support.v7.view.ActionMode;
303954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.util.Log;
3130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.Menu;
3230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuInflater;
3330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuItem;
343954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.view.View;
353954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesimport android.view.ViewGroup;
363954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
373954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banesabstract class ActionBarActivityDelegate {
383954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
393954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    static final String METADATA_UI_OPTIONS = "android.support.UI_OPTIONS";
403954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    static final String UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW = "splitActionBarWhenNarrow";
413954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
423954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    private static final String TAG = "ActionBarActivityDelegate";
433954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
445a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    static ActionBarActivityDelegate createDelegate(ActionBarActivity activity) {
455a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        final int version = Build.VERSION.SDK_INT;
465a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        if (version >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
475a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes            return new ActionBarActivityDelegateICS(activity);
488123e4b3d19031e34a60c0db202f0b3d100eb9d8Chris Banes        } else if (version >= Build.VERSION_CODES.HONEYCOMB) {
498123e4b3d19031e34a60c0db202f0b3d100eb9d8Chris Banes            return new ActionBarActivityDelegateHC(activity);
505a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        } else {
51f2b7cd67036d78fd5b487b0a2dab28aee11d9c88Adam Powell            return new ActionBarActivityDelegateBase(activity);
525a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        }
535a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    }
545a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes
553954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    final ActionBarActivity mActivity;
563954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
575a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    private ActionBar mActionBar;
585a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    private MenuInflater mMenuInflater;
595a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes
605a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    // true if this activity has an action bar.
615a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    boolean mHasActionBar;
625a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    // true if this activity's action bar overlays other activity content.
635a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    boolean mOverlayActionBar;
645a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes
653954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    ActionBarActivityDelegate(ActionBarActivity activity) {
663954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes        mActivity = activity;
673954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    }
683954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
693954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    abstract ActionBar createSupportActionBar();
703954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
715a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    final ActionBar getSupportActionBar() {
725a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        // The Action Bar should be lazily created as mHasActionBar or mOverlayActionBar
735a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        // could change after onCreate
745a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        if (mHasActionBar || mOverlayActionBar) {
755a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes            if (mActionBar == null) {
765a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes                mActionBar = createSupportActionBar();
775a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes            }
785a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        } else {
795a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes            // If we're not set to have a Action Bar, null it just in case it's been set
805a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes            mActionBar = null;
815a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        }
825a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        return mActionBar;
835a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    }
845a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes
8503527a1c5ca870353671fd8b97a08a989fe62012Chris Banes    MenuInflater getMenuInflater() {
865a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        if (mMenuInflater == null) {
87baf2251209e04f0dac4ec7e5d8c0bfc0014c4038Chris Banes            ActionBar ab = getSupportActionBar();
88baf2251209e04f0dac4ec7e5d8c0bfc0014c4038Chris Banes            if (ab != null) {
89baf2251209e04f0dac4ec7e5d8c0bfc0014c4038Chris Banes                mMenuInflater = new SupportMenuInflater(ab.getThemedContext());
90baf2251209e04f0dac4ec7e5d8c0bfc0014c4038Chris Banes            } else {
91baf2251209e04f0dac4ec7e5d8c0bfc0014c4038Chris Banes                mMenuInflater = new SupportMenuInflater(mActivity);
92baf2251209e04f0dac4ec7e5d8c0bfc0014c4038Chris Banes            }
935a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        }
945a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        return mMenuInflater;
955a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    }
965a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes
975a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    void onCreate(Bundle savedInstanceState) {
985a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        TypedArray a = mActivity.obtainStyledAttributes(R.styleable.ActionBarWindow);
995a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes
1005a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        if (!a.hasValue(R.styleable.ActionBarWindow_windowActionBar)) {
1015a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes            a.recycle();
1025a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes            throw new IllegalStateException(
1035a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes                    "You need to use a Theme.AppCompat theme (or descendant) with this activity.");
1045a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        }
1055a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes
1065a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        mHasActionBar = a.getBoolean(R.styleable.ActionBarWindow_windowActionBar, false);
1075a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        mOverlayActionBar = a.getBoolean(R.styleable.ActionBarWindow_windowActionBarOverlay, false);
1085a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        a.recycle();
1095a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    }
1103954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
1113954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    abstract void onConfigurationChanged(Configuration newConfig);
1123954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
113a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    abstract void onStop();
114a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes
115a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    abstract void onPostResume();
116a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes
1173954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    abstract void setContentView(View v);
1183954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
1193954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    abstract void setContentView(int resId);
1203954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
1213954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    abstract void setContentView(View v, ViewGroup.LayoutParams lp);
1223954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
1233954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    abstract void addContentView(View v, ViewGroup.LayoutParams lp);
1243954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
125904507029cd8ea2d070b6df0911b2dd36b7075a6Chris Banes    abstract void onTitleChanged(CharSequence title);
1263954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
1273954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    abstract void supportInvalidateOptionsMenu();
1283954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
129ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    abstract boolean supportRequestWindowFeature(int featureId);
130ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
1313954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    // Methods used to create and respond to options menu
1323954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    abstract View onCreatePanelView(int featureId);
1333954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
13430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    abstract boolean onPreparePanel(int featureId, View view, Menu menu);
1353954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
13630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    abstract boolean onCreatePanelMenu(int featureId, Menu menu);
1373954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
13830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    abstract boolean onMenuItemSelected(int featureId, MenuItem item);
1393954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
140d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    abstract boolean onBackPressed();
141d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
142d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    abstract ActionMode startSupportActionMode(ActionMode.Callback callback);
143d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
14430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    abstract void setSupportProgressBarVisibility(boolean visible);
145ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
146ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    abstract void setSupportProgressBarIndeterminateVisibility(boolean visible);
147ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
148ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    abstract void setSupportProgressBarIndeterminate(boolean indeterminate);
149ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
150ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    abstract void setSupportProgress(int progress);
151ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
15245d973fcc4c43f5ea00cddd3d9b947d9e8d8fc4eChris Banes    abstract ActionBarDrawerToggle.Delegate getDrawerToggleDelegate();
15345d973fcc4c43f5ea00cddd3d9b947d9e8d8fc4eChris Banes
1543954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    protected final String getUiOptionsFromMetadata() {
1553954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes        try {
1563954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes            PackageManager pm = mActivity.getPackageManager();
1573954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes            ActivityInfo info = pm.getActivityInfo(mActivity.getComponentName(),
1583954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes                    PackageManager.GET_META_DATA);
1593954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
1603954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes            String uiOptions = null;
1613954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes            if (info.metaData != null) {
1623954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes                uiOptions = info.metaData.getString(METADATA_UI_OPTIONS);
1633954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes            }
1643954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes            return uiOptions;
1653954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes        } catch (PackageManager.NameNotFoundException e) {
1663954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes            Log.e(TAG, "getUiOptionsFromMetadata: Activity '" + mActivity.getClass()
1673954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes                    .getSimpleName() + "' not in manifest");
1683954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes            return null;
1693954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes        }
1703954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes    }
1713954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
172d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    protected final Context getActionBarThemedContext() {
173d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        Context context = mActivity;
174d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
175d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        // If we have an action bar, initialize the menu with a context themed from it.
1765a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        ActionBar ab = getSupportActionBar();
177d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        if (ab != null) {
178d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            context = ab.getThemedContext();
179d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
180d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        return context;
181d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    }
1823954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes}
183