1239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar/*
2239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * Copyright (C) 2014 The Android Open Source Project
3239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar *
4239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
5239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * you may not use this file except in compliance with the License.
6239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * You may obtain a copy of the License at
7239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar *
8239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
9239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar *
10239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * Unless required by applicable law or agreed to in writing, software
11239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
12239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * See the License for the specific language governing permissions and
14239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * limitations under the License.
15239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar */
16239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
17239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
18239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyarpackage android.support.v7.app;
19239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
20239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyarimport android.R;
21239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyarimport android.app.ActionBar;
22239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyarimport android.app.Activity;
23239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyarimport android.content.res.TypedArray;
24239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyarimport android.graphics.drawable.Drawable;
25239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyarimport android.os.Build;
26239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyarimport android.util.Log;
27239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyarimport android.view.View;
28239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyarimport android.view.ViewGroup;
29239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyarimport android.widget.ImageView;
30239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
31239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyarimport java.lang.reflect.Method;
32239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
33239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar/**
34239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * This class encapsulates some awful hacks.
35239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar *
36239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * Before JB-MR2 (API 18) it was not possible to change the home-as-up indicator glyph
37239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * in an action bar without some really gross hacks. Since the MR2 SDK is not published as of
38239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * this writing, the new API is accessed via reflection here if available.
39239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar *
40239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar * Moved from Support-v4
41239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar */
42239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyarclass ActionBarDrawerToggleHoneycomb {
43239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar    private static final String TAG = "ActionBarDrawerToggleHoneycomb";
44239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
45239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar    private static final int[] THEME_ATTRS = new int[] {
46239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            R.attr.homeAsUpIndicator
47239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar    };
48239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
49239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar    public static SetIndicatorInfo setActionBarUpIndicator(SetIndicatorInfo info, Activity activity,
50239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            Drawable drawable, int contentDescRes) {
51239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        if (true || info == null) {
52239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            info = new SetIndicatorInfo(activity);
53239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        }
54239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        if (info.setHomeAsUpIndicator != null) {
55239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            try {
56239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                final ActionBar actionBar = activity.getActionBar();
57239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                info.setHomeAsUpIndicator.invoke(actionBar, drawable);
58239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                info.setHomeActionContentDescription.invoke(actionBar, contentDescRes);
59239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            } catch (Exception e) {
60239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                Log.w(TAG, "Couldn't set home-as-up indicator via JB-MR2 API", e);
61239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            }
62239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        } else if (info.upIndicatorView != null) {
63239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            info.upIndicatorView.setImageDrawable(drawable);
64239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        } else {
65239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            Log.w(TAG, "Couldn't set home-as-up indicator");
66239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        }
67239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        return info;
68239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar    }
69239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
70239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar    public static SetIndicatorInfo setActionBarDescription(SetIndicatorInfo info, Activity activity,
71239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            int contentDescRes) {
72239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        if (info == null) {
73239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            info = new SetIndicatorInfo(activity);
74239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        }
75239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        if (info.setHomeAsUpIndicator != null) {
76239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            try {
77239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                final ActionBar actionBar = activity.getActionBar();
78239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                info.setHomeActionContentDescription.invoke(actionBar, contentDescRes);
79239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                if (Build.VERSION.SDK_INT <= 19) {
80239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                    // For API 19 and earlier, we need to manually force the
81239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                    // action bar to generate a new content description.
82239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                    actionBar.setSubtitle(actionBar.getSubtitle());
83239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                }
84239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            } catch (Exception e) {
85239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                Log.w(TAG, "Couldn't set content description via JB-MR2 API", e);
86239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            }
87239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        }
88239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        return info;
89239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar    }
90239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
91239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar    public static Drawable getThemeUpIndicator(Activity activity) {
92239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        final TypedArray a = activity.obtainStyledAttributes(THEME_ATTRS);
93239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        final Drawable result = a.getDrawable(0);
94239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        a.recycle();
95239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        return result;
96239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar    }
97239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
98239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar    static class SetIndicatorInfo {
99239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        public Method setHomeAsUpIndicator;
100239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        public Method setHomeActionContentDescription;
101239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        public ImageView upIndicatorView;
102239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
103239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        SetIndicatorInfo(Activity activity) {
104239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            try {
105239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                setHomeAsUpIndicator = ActionBar.class.getDeclaredMethod("setHomeAsUpIndicator",
106239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                        Drawable.class);
107239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                setHomeActionContentDescription = ActionBar.class.getDeclaredMethod(
108239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                        "setHomeActionContentDescription", Integer.TYPE);
109239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
110239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                // If we got the method we won't need the stuff below.
111239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                return;
112239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            } catch (NoSuchMethodException e) {
113239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                // Oh well. We'll use the other mechanism below instead.
114239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            }
115239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
116239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            final View home = activity.findViewById(android.R.id.home);
117239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            if (home == null) {
118239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                // Action bar doesn't have a known configuration, an OEM messed with things.
119239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                return;
120239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            }
121239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
122239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            final ViewGroup parent = (ViewGroup) home.getParent();
123239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            final int childCount = parent.getChildCount();
124239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            if (childCount != 2) {
125239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                // No idea which one will be the right one, an OEM messed with things.
126239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                return;
127239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            }
128239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
129239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            final View first = parent.getChildAt(0);
130239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            final View second = parent.getChildAt(1);
131239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            final View up = first.getId() == android.R.id.home ? second : first;
132239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar
133239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            if (up instanceof ImageView) {
134239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                // Jackpot! (Probably...)
135239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar                upIndicatorView = (ImageView) up;
136239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar            }
137239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar        }
138239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar    }
139239e759c480945ee5c164c7c75cb30ff164caa91Yigit Boyar}
140