1 /* 2 * Copyright 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 package com.android.angle.common; 17 18 import android.content.BroadcastReceiver; 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.SharedPreferences; 22 import android.database.ContentObserver; 23 import android.net.Uri; 24 import android.os.Bundle; 25 import android.os.Handler; 26 import android.provider.Settings; 27 import android.text.TextUtils; 28 import android.util.Log; 29 30 import androidx.preference.PreferenceManager; 31 32 import org.json.JSONArray; 33 import org.json.JSONException; 34 import org.json.JSONObject; 35 36 import java.io.IOException; 37 import java.io.InputStream; 38 import java.util.Collections; 39 import java.util.List; 40 import java.util.stream.Stream; 41 42 import com.android.angle.R; 43 44 public class Receiver extends BroadcastReceiver 45 { 46 private static final String TAG = "AngleBroadcastReceiver"; 47 private static final boolean DEBUG = false; 48 49 @Override onReceive(Context context, Intent intent)50 public void onReceive(Context context, Intent intent) 51 { 52 final String action = intent.getAction(); 53 if (DEBUG) 54 { 55 Log.d(TAG, "Received intent: " + action); 56 } 57 58 if (action.equals(context.getString(R.string.intent_angle_for_android_toast_message))) 59 { 60 Bundle results = getResultExtras(true); 61 results.putString(context.getString(R.string.intent_key_a4a_toast_message), 62 context.getString(R.string.angle_in_use_toast_message)); 63 } 64 else if (action.equals(Intent.ACTION_BOOT_COMPLETED) || action.equals(Intent.ACTION_MY_PACKAGE_REPLACED)) 65 { 66 AngleRuleHelper angleRuleHelper = new AngleRuleHelper(context); 67 updateGlobalSettings(context, angleRuleHelper); 68 updateDeveloperOptionsWatcher(context); 69 } 70 } 71 72 /** 73 * Consume the results of rule parsing to populate global settings 74 */ updateGlobalSettings(Context context, AngleRuleHelper angleRuleHelper)75 private static void updateGlobalSettings(Context context, AngleRuleHelper angleRuleHelper) 76 { 77 int count = 0; 78 String packages = ""; 79 String choices = ""; 80 81 // Bring in the packages and choices and convert them to global settings format 82 final List<String> anglePackages = angleRuleHelper.getPackageNamesForAngle(); 83 final List<String> nativePackages = angleRuleHelper.getPackageNamesForNative(); 84 85 // packages = anglePackage1,anglePackage2,nativePackage1,nativePackage2 86 packages = String.join(",", Stream.concat( 87 anglePackages.stream(), 88 nativePackages.stream()) 89 .toList()); 90 91 // choices = angle,angle,native,native 92 choices = String.join(",", Stream.concat( 93 Collections.nCopies( 94 anglePackages.size(), "angle") 95 .stream(), 96 Collections.nCopies( 97 nativePackages.size(), "native") 98 .stream()) 99 .toList()); 100 101 Log.v(TAG, "Updating ANGLE global settings with:" + 102 " packages = " + packages + 103 " choices = " + choices); 104 GlobalSettings.writeGlobalSettings(context, packages, choices); 105 } 106 107 /** 108 * When Developer Options are disabled, reset all of the global settings back to their defaults. 109 */ updateDeveloperOptionsWatcher(Context context)110 private static void updateDeveloperOptionsWatcher(Context context) 111 { 112 final Uri settingUri = Settings.Global.getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED); 113 114 final ContentObserver developerOptionsObserver = new ContentObserver(new Handler()) { 115 @Override 116 public void onChange(boolean selfChange) 117 { 118 super.onChange(selfChange); 119 120 final boolean developerOptionsEnabled = 121 (1 122 == Settings.Global.getInt(context.getContentResolver(), 123 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0)); 124 125 Log.v(TAG, "Developer Options enabled value changed: " 126 + "developerOptionsEnabled = " + developerOptionsEnabled); 127 128 if (!developerOptionsEnabled) 129 { 130 // Reset the necessary settings to their defaults. 131 SharedPreferences.Editor editor = 132 PreferenceManager.getDefaultSharedPreferences(context).edit(); 133 editor.clear(); 134 editor.apply(); 135 GlobalSettings.clearGlobalSettings(context); 136 } 137 } 138 }; 139 140 context.getContentResolver().registerContentObserver( 141 settingUri, false, developerOptionsObserver); 142 } 143 } 144