1 /* 2 * Copyright (C) 2019 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.quickstep; 18 19 import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter; 20 21 import android.content.BroadcastReceiver; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.res.Resources; 25 import android.util.Log; 26 27 import com.android.launcher3.util.MainThreadInitializedObject; 28 29 import java.util.ArrayList; 30 import java.util.List; 31 32 /** 33 * Observer for the resource config that specifies the navigation bar mode. 34 */ 35 public class SysUINavigationMode { 36 37 public enum Mode { 38 THREE_BUTTONS(false, 0), 39 TWO_BUTTONS(true, 1), 40 NO_BUTTON(true, 2); 41 42 public final boolean hasGestures; 43 public final int resValue; 44 Mode(boolean hasGestures, int resValue)45 Mode(boolean hasGestures, int resValue) { 46 this.hasGestures = hasGestures; 47 this.resValue = resValue; 48 } 49 } 50 getMode(Context context)51 public static Mode getMode(Context context) { 52 return INSTANCE.get(context).getMode(); 53 } 54 55 public static MainThreadInitializedObject<SysUINavigationMode> INSTANCE = 56 new MainThreadInitializedObject<>(SysUINavigationMode::new); 57 58 private static final String TAG = "SysUINavigationMode"; 59 60 private final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED"; 61 private static final String NAV_BAR_INTERACTION_MODE_RES_NAME = 62 "config_navBarInteractionMode"; 63 64 private final Context mContext; 65 private Mode mMode; 66 67 private final List<NavigationModeChangeListener> mChangeListeners = new ArrayList<>(); 68 SysUINavigationMode(Context context)69 public SysUINavigationMode(Context context) { 70 mContext = context; 71 initializeMode(); 72 73 mContext.registerReceiver(new BroadcastReceiver() { 74 @Override 75 public void onReceive(Context context, Intent intent) { 76 Mode oldMode = mMode; 77 initializeMode(); 78 if (mMode != oldMode) { 79 dispatchModeChange(); 80 } 81 } 82 }, getPackageFilter("android", ACTION_OVERLAY_CHANGED)); 83 } 84 initializeMode()85 private void initializeMode() { 86 int modeInt = getSystemIntegerRes(mContext, NAV_BAR_INTERACTION_MODE_RES_NAME); 87 for(Mode m : Mode.values()) { 88 if (m.resValue == modeInt) { 89 mMode = m; 90 } 91 } 92 } 93 dispatchModeChange()94 private void dispatchModeChange() { 95 for (NavigationModeChangeListener listener : mChangeListeners) { 96 listener.onNavigationModeChanged(mMode); 97 } 98 } 99 addModeChangeListener(NavigationModeChangeListener listener)100 public Mode addModeChangeListener(NavigationModeChangeListener listener) { 101 mChangeListeners.add(listener); 102 return mMode; 103 } 104 removeModeChangeListener(NavigationModeChangeListener listener)105 public void removeModeChangeListener(NavigationModeChangeListener listener) { 106 mChangeListeners.remove(listener); 107 } 108 getMode()109 public Mode getMode() { 110 return mMode; 111 } 112 getSystemIntegerRes(Context context, String resName)113 private static int getSystemIntegerRes(Context context, String resName) { 114 Resources res = context.getResources(); 115 int resId = res.getIdentifier(resName, "integer", "android"); 116 117 if (resId != 0) { 118 return res.getInteger(resId); 119 } else { 120 Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?"); 121 return -1; 122 } 123 } 124 125 public interface NavigationModeChangeListener { 126 onNavigationModeChanged(Mode newMode)127 void onNavigationModeChanged(Mode newMode); 128 } 129 }