1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.statusbar.car; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.res.TypedArray; 22 import android.os.UserHandle; 23 import android.util.AttributeSet; 24 import android.util.Log; 25 import android.widget.ImageView; 26 27 import com.android.systemui.R; 28 29 import java.net.URISyntaxException; 30 31 /** 32 * CarNavigationButton is an image button that allows for a bit more configuration at the 33 * xml file level. This allows for more control via overlays instead of having to update 34 * code. 35 */ 36 public class CarNavigationButton extends com.android.keyguard.AlphaOptimizedImageButton { 37 private static final String TAG = "CarNavigationButton"; 38 39 private static final int UNSEEN_ICON_RESOURCE_ID = R.drawable.car_ic_notification_unseen; 40 private static final int UNSEEN_SELECTED_ICON_RESOURCE_ID = 41 R.drawable.car_ic_notification_selected_unseen; 42 43 private Context mContext; 44 private String mIntent; 45 private String mLongIntent; 46 private boolean mBroadcastIntent; 47 private boolean mHasUnseen = false; 48 private boolean mSelected = false; 49 private float mSelectedAlpha = 1f; 50 private float mUnselectedAlpha = 1f; 51 private int mSelectedIconResourceId; 52 private int mIconResourceId; 53 54 CarNavigationButton(Context context, AttributeSet attrs)55 public CarNavigationButton(Context context, AttributeSet attrs) { 56 super(context, attrs); 57 mContext = context; 58 59 // CarNavigationButton attrs 60 TypedArray typedArray = context.obtainStyledAttributes( 61 attrs, R.styleable.CarNavigationButton); 62 mIntent = typedArray.getString(R.styleable.CarNavigationButton_intent); 63 mLongIntent = typedArray.getString(R.styleable.CarNavigationButton_longIntent); 64 mBroadcastIntent = typedArray.getBoolean(R.styleable.CarNavigationButton_broadcast, false); 65 mSelectedAlpha = typedArray.getFloat( 66 R.styleable.CarNavigationButton_selectedAlpha, mSelectedAlpha); 67 mUnselectedAlpha = typedArray.getFloat( 68 R.styleable.CarNavigationButton_unselectedAlpha, mUnselectedAlpha); 69 mSelectedIconResourceId = typedArray.getResourceId( 70 R.styleable.CarNavigationButton_selectedIcon, mIconResourceId); 71 typedArray.recycle(); 72 73 // ImageView attrs 74 TypedArray a = context.obtainStyledAttributes( 75 attrs, com.android.internal.R.styleable.ImageView); 76 mIconResourceId = a.getResourceId(com.android.internal.R.styleable.ImageView_src, 0); 77 a.recycle(); 78 } 79 80 81 /** 82 * After the standard inflate this then adds the xml defined intents to click and long click 83 * actions if defined. 84 */ 85 @Override onFinishInflate()86 public void onFinishInflate() { 87 super.onFinishInflate(); 88 setScaleType(ImageView.ScaleType.CENTER); 89 setAlpha(mUnselectedAlpha); 90 try { 91 if (mIntent != null) { 92 final Intent intent = Intent.parseUri(mIntent, Intent.URI_INTENT_SCHEME); 93 setOnClickListener(v -> { 94 try { 95 if (mBroadcastIntent) { 96 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); 97 return; 98 } 99 mContext.startActivityAsUser(intent, UserHandle.CURRENT); 100 } catch (Exception e) { 101 Log.e(TAG, "Failed to launch intent", e); 102 } 103 }); 104 } 105 } catch (URISyntaxException e) { 106 throw new RuntimeException("Failed to attach intent", e); 107 } 108 109 try { 110 if (mLongIntent != null) { 111 final Intent intent = Intent.parseUri(mLongIntent, Intent.URI_INTENT_SCHEME); 112 setOnLongClickListener(v -> { 113 try { 114 mContext.startActivityAsUser(intent, UserHandle.CURRENT); 115 } catch (Exception e) { 116 Log.e(TAG, "Failed to launch intent", e); 117 } 118 // consume event either way 119 return true; 120 }); 121 } 122 } catch (URISyntaxException e) { 123 throw new RuntimeException("Failed to attach long press intent", e); 124 } 125 } 126 127 /** 128 * @param selected true if should indicate if this is a selected state, false otherwise 129 */ setSelected(boolean selected)130 public void setSelected(boolean selected) { 131 super.setSelected(selected); 132 mSelected = selected; 133 setAlpha(mSelected ? mSelectedAlpha : mUnselectedAlpha); 134 updateImage(); 135 } 136 137 /** 138 * @param hasUnseen true if should indicate if this is a Unseen state, false otherwise. 139 */ setUnseen(boolean hasUnseen)140 public void setUnseen(boolean hasUnseen) { 141 mHasUnseen = hasUnseen; 142 updateImage(); 143 } 144 updateImage()145 private void updateImage() { 146 if (mHasUnseen) { 147 setImageResource(mSelected ? UNSEEN_SELECTED_ICON_RESOURCE_ID 148 : UNSEEN_ICON_RESOURCE_ID); 149 } else { 150 setImageResource(mSelected ? mSelectedIconResourceId : mIconResourceId); 151 } 152 } 153 } 154