1 /* 2 * Copyright (C) 2021 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.settings.activityembedding; 18 19 import android.app.Activity; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.util.LayoutDirection; 24 import android.util.Log; 25 26 import androidx.window.embedding.ActivityFilter; 27 import androidx.window.embedding.ActivityRule; 28 import androidx.window.embedding.SplitController; 29 import androidx.window.embedding.SplitPairFilter; 30 import androidx.window.embedding.SplitPairRule; 31 import androidx.window.embedding.SplitPlaceholderRule; 32 import androidx.window.embedding.SplitRule; 33 34 import com.android.settings.Settings; 35 import com.android.settings.SubSettings; 36 import com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling; 37 import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroduction; 38 import com.android.settings.homepage.DeepLinkHomepageActivity; 39 import com.android.settings.homepage.SettingsHomepageActivity; 40 import com.android.settings.homepage.SliceDeepLinkHomepageActivity; 41 42 import java.util.HashSet; 43 import java.util.Set; 44 45 /** A class to initialize split rules for activity embedding. */ 46 public class ActivityEmbeddingRulesController { 47 48 private static final String TAG = "ActivityEmbeddingCtrl"; 49 private final Context mContext; 50 private final SplitController mSplitController; 51 ActivityEmbeddingRulesController(Context context)52 public ActivityEmbeddingRulesController(Context context) { 53 mContext = context; 54 mSplitController = SplitController.getInstance(); 55 } 56 57 /** 58 * Set up embedding rules to place activities to the right pane. 59 */ initRules()60 public void initRules() { 61 if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(mContext)) { 62 Log.d(TAG, "Not support this feature now"); 63 return; 64 } 65 66 mSplitController.clearRegisteredRules(); 67 68 // Set a placeholder for home page. 69 registerHomepagePlaceholderRule(); 70 71 registerAlwaysExpandRule(); 72 } 73 74 /** Register a SplitPairRule for 2-pane. */ registerTwoPanePairRule(Context context, ComponentName primaryComponent, ComponentName secondaryComponent, String secondaryIntentAction, int finishPrimaryWithSecondary, int finishSecondaryWithPrimary, boolean clearTop)75 public static void registerTwoPanePairRule(Context context, 76 ComponentName primaryComponent, 77 ComponentName secondaryComponent, 78 String secondaryIntentAction, 79 int finishPrimaryWithSecondary, 80 int finishSecondaryWithPrimary, 81 boolean clearTop) { 82 if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(context)) { 83 return; 84 } 85 final Set<SplitPairFilter> filters = new HashSet<>(); 86 filters.add(new SplitPairFilter(primaryComponent, secondaryComponent, 87 secondaryIntentAction)); 88 89 SplitController.getInstance().registerRule(new SplitPairRule(filters, 90 finishPrimaryWithSecondary, 91 finishSecondaryWithPrimary, 92 clearTop, 93 ActivityEmbeddingUtils.getMinCurrentScreenSplitWidthPx(context), 94 ActivityEmbeddingUtils.getMinSmallestScreenSplitWidthPx(context), 95 ActivityEmbeddingUtils.SPLIT_RATIO, 96 LayoutDirection.LOCALE)); 97 } 98 99 /** 100 * Register a new SplitPairRule for Settings home. Because homepage is able to be opened by 101 * {@link Settings} or {@link SettingsHomepageActivity} or 102 * {@link SliceDeepLinkHomepageActivity}, we register split rule for above cases. 103 */ registerTwoPanePairRuleForSettingsHome(Context context, ComponentName secondaryComponent, String secondaryIntentAction, boolean finishPrimaryWithSecondary, boolean finishSecondaryWithPrimary, boolean clearTop)104 public static void registerTwoPanePairRuleForSettingsHome(Context context, 105 ComponentName secondaryComponent, 106 String secondaryIntentAction, 107 boolean finishPrimaryWithSecondary, 108 boolean finishSecondaryWithPrimary, 109 boolean clearTop) { 110 if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(context)) { 111 return; 112 } 113 114 registerTwoPanePairRule( 115 context, 116 new ComponentName(context, Settings.class), 117 secondaryComponent, 118 secondaryIntentAction, 119 finishPrimaryWithSecondary ? SplitRule.FINISH_ADJACENT : SplitRule.FINISH_NEVER, 120 finishSecondaryWithPrimary ? SplitRule.FINISH_ADJACENT : SplitRule.FINISH_NEVER, 121 clearTop); 122 123 registerTwoPanePairRule( 124 context, 125 new ComponentName(context, SettingsHomepageActivity.class), 126 secondaryComponent, 127 secondaryIntentAction, 128 finishPrimaryWithSecondary ? SplitRule.FINISH_ADJACENT : SplitRule.FINISH_NEVER, 129 finishSecondaryWithPrimary ? SplitRule.FINISH_ADJACENT : SplitRule.FINISH_NEVER, 130 clearTop); 131 132 // We should finish HomePageActivity altogether even if it shows in single pane for all deep 133 // link cases. 134 registerTwoPanePairRule( 135 context, 136 new ComponentName(context, DeepLinkHomepageActivity.class), 137 secondaryComponent, 138 secondaryIntentAction, 139 finishPrimaryWithSecondary ? SplitRule.FINISH_ALWAYS : SplitRule.FINISH_NEVER, 140 finishSecondaryWithPrimary ? SplitRule.FINISH_ALWAYS : SplitRule.FINISH_NEVER, 141 clearTop); 142 143 registerTwoPanePairRule( 144 context, 145 new ComponentName(context, SliceDeepLinkHomepageActivity.class), 146 secondaryComponent, 147 secondaryIntentAction, 148 finishPrimaryWithSecondary ? SplitRule.FINISH_ALWAYS : SplitRule.FINISH_NEVER, 149 finishSecondaryWithPrimary ? SplitRule.FINISH_ALWAYS : SplitRule.FINISH_NEVER, 150 clearTop); 151 } 152 153 /** 154 * Register a new SplitPairRule for Settings home. 155 */ registerTwoPanePairRuleForSettingsHome(Context context, ComponentName secondaryComponent, String secondaryIntentAction, boolean clearTop)156 public static void registerTwoPanePairRuleForSettingsHome(Context context, 157 ComponentName secondaryComponent, 158 String secondaryIntentAction, 159 boolean clearTop) { 160 if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(context)) { 161 return; 162 } 163 164 registerTwoPanePairRuleForSettingsHome( 165 context, 166 secondaryComponent, 167 secondaryIntentAction, 168 true /* finishPrimaryWithSecondary */, 169 true /* finishSecondaryWithPrimary */, 170 clearTop); 171 } 172 173 /** Register a SplitPairRule for SubSettings if the device supports 2-pane. */ registerSubSettingsPairRule(Context context, boolean clearTop)174 public static void registerSubSettingsPairRule(Context context, boolean clearTop) { 175 if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(context)) { 176 return; 177 } 178 179 registerTwoPanePairRuleForSettingsHome( 180 context, 181 new ComponentName(context, SubSettings.class), 182 null /* secondaryIntentAction */, 183 clearTop); 184 } 185 registerHomepagePlaceholderRule()186 private void registerHomepagePlaceholderRule() { 187 final Set<ActivityFilter> activityFilters = new HashSet<>(); 188 addActivityFilter(activityFilters, SettingsHomepageActivity.class); 189 addActivityFilter(activityFilters, DeepLinkHomepageActivity.class); 190 addActivityFilter(activityFilters, SliceDeepLinkHomepageActivity.class); 191 addActivityFilter(activityFilters, Settings.class); 192 193 final Intent intent = new Intent(mContext, Settings.NetworkDashboardActivity.class); 194 final SplitPlaceholderRule placeholderRule = new SplitPlaceholderRule( 195 activityFilters, 196 intent, 197 true /* stickyPlaceholder */, 198 SplitRule.FINISH_ADJACENT, 199 ActivityEmbeddingUtils.getMinCurrentScreenSplitWidthPx(mContext), 200 ActivityEmbeddingUtils.getMinSmallestScreenSplitWidthPx(mContext), 201 ActivityEmbeddingUtils.SPLIT_RATIO, 202 LayoutDirection.LOCALE); 203 204 mSplitController.registerRule(placeholderRule); 205 } 206 registerAlwaysExpandRule()207 private void registerAlwaysExpandRule() { 208 final Set<ActivityFilter> activityFilters = new HashSet<>(); 209 addActivityFilter(activityFilters, FingerprintEnrollIntroduction.class); 210 addActivityFilter(activityFilters, FingerprintEnrollEnrolling.class); 211 mSplitController.registerRule(new ActivityRule(activityFilters, true /* alwaysExpand */)); 212 } 213 addActivityFilter(Set<ActivityFilter> activityFilters, Class<? extends Activity> activityClass)214 private void addActivityFilter(Set<ActivityFilter> activityFilters, 215 Class<? extends Activity> activityClass) { 216 activityFilters.add(new ActivityFilter(new ComponentName(mContext, activityClass), 217 null /* intentAction */)); 218 } 219 } 220