Skip to content

Commit

Permalink
UPDATE: Minor tweaks.
Browse files Browse the repository at this point in the history
  • Loading branch information
oasisfeng committed Oct 14, 2020
1 parent 3587836 commit eaee381
Show file tree
Hide file tree
Showing 11 changed files with 34 additions and 25 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ allprojects {
jcenter()
}

ext.compileSdkVersion = 29
ext.compileSdkVersion = 30
ext.minSdkVersion = 24
}
2 changes: 1 addition & 1 deletion mobile/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

android {
compileSdkVersion 30
compileSdkVersion this.compileSdkVersion

defaultConfig {
minSdkVersion this.minSdkVersion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ public void onTabSwitched(final FragmentActivity activity, final TabLayout tabs,
mFeatured.visible.setValue(Boolean.TRUE);
mFeatured.update(activity);
mChipsVisible.setValue(false);
Analytics.log(TAG, "tab-discover");
return;
} else mFeatured.visible.setValue(Boolean.FALSE);

Expand All @@ -201,13 +202,15 @@ public void onTabSwitched(final FragmentActivity activity, final TabLayout tabs,
if (Users.isProfileManagedByIsland(profile)) {
setCurrentProfile(profile);
updateAppList();
Analytics.log(TAG, "tab-island-" + UserHandles.getIdentifier(profile));
return;
}
}
}
tabs.selectTab(tabs.getTabAt(1)); // Switch back to Mainland
setCurrentProfile(Users.owner);
updateAppList();
Analytics.log(TAG, "tab-mainland");
}

public void updateActions(final Menu menu) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import android.util.Log
import android.widget.Toast
import androidx.lifecycle.viewModelScope
import com.oasisfeng.common.app.BaseAndroidViewModel
import com.oasisfeng.island.analytics.analytics
import com.oasisfeng.island.analytics.Analytics
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.future.future
Expand All @@ -23,6 +23,6 @@ fun <R> BaseAndroidViewModel.interactiveFuture(context: Context, block: suspend

private fun handleException(context: Context, tag: String, t: Throwable) {
if (t is CancellationException) return Unit.also { Log.i(tag, "Interaction canceled: ${t.message}") }
analytics().logAndReport(tag, "Unexpected internal error", t)
Analytics().logAndReport(tag, "Unexpected internal error", t)
Toast.makeText(context, "Internal error: " + t.message, Toast.LENGTH_LONG).show()
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

package com.oasisfeng.island.settings

import android.Manifest.permission.*
import android.Manifest.permission.ACCESS_COARSE_LOCATION
import android.Manifest.permission.READ_EXTERNAL_STORAGE
import android.Manifest.permission.READ_PHONE_STATE
import android.Manifest.permission.READ_SMS
import android.annotation.SuppressLint
import android.app.Activity
import android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE
Expand Down Expand Up @@ -91,15 +94,15 @@ class IslandSettingsFragment: android.preference.PreferenceFragment() {
.filter { it.requestedPermissions?.contains(INTERACT_ACROSS_PROFILES) == true }
val pm = activity.packageManager
val entries = pkgs.map { it.applicationInfo.loadLabel(pm) }.toTypedArray()
val allowedPackages = policies.invoke(DPM::getCrossProfilePackages)
val allowedPackages: Set<String> = policies.invoke(DPM::getCrossProfilePackages)
val allowed = BooleanArray(entries.size) { index -> pkgs[index].packageName in allowedPackages }
Dialogs.buildCheckList(activity, activity.getText(R.string.prompt_manage_cross_profile_apps),
entries, allowed) { _, which, checked -> allowed[which] = checked }.withOkButton {
pkgs.mapIndexedNotNullTo(ArraySet()) { index, pkg -> if (allowed[index]) pkg.packageName else null }
.toSet().also { policies.invoke(DPM::setCrossProfilePackages, it) }}
.withCancelButton().show() }}

setupNotificationChannelTwoStatePreference(R.string.key_island_watcher, SDK_INT >= P && ! Users.isOwner(), NotificationIds.IslandWatcher)
setupNotificationChannelTwoStatePreference(R.string.key_island_watcher, SDK_INT >= P && !Users.isOwner(), NotificationIds.IslandWatcher)
setupNotificationChannelTwoStatePreference(R.string.key_app_watcher, SDK_INT >= O, NotificationIds.IslandAppWatcher)

setup<Preference>(R.string.key_reprovision) {
Expand Down Expand Up @@ -128,7 +131,7 @@ class IslandSettingsFragment: android.preference.PreferenceFragment() {
setup<TwoStatePreference>(key) {
if (visible && SDK_INT >= O) {
isChecked = ! notificationId.isBlocked(context)
setOnPreferenceChangeListener { _,_ -> true.also { context.startActivity(notificationId.buildChannelSettingsIntent(context)) }}
setOnPreferenceChangeListener { _, _ -> true.also { context.startActivity(notificationId.buildChannelSettingsIntent(context)) }}
} else remove(this)
}
}
Expand All @@ -149,11 +152,11 @@ class IslandSettingsFragment: android.preference.PreferenceFragment() {
if (text.isNullOrEmpty()) text = IslandNameManager.getDefaultName(activity)
editText.also { editText ->
editText.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}

override fun afterTextChanged(s: Editable) {
if (editText.text.any { it < ' ' }) editText.error = getString(R.string.prompt_invalid_input) }})
override fun afterTextChanged(s: Editable) {
if (editText.text.any { it < ' ' }) editText.error = getString(R.string.prompt_invalid_input) }})

setOnPreferenceChangeListener { _, name -> (editText.error == null).also { if (it)
onIslandRenamed(name.toString()) }}
Expand Down Expand Up @@ -217,3 +220,5 @@ class IslandSettingsActivity: Activity() {
}
}
}

private const val INTERACT_ACROSS_PROFILES = "android.permission.INTERACT_ACROSS_PROFILES"
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,13 @@ class DelegatedScopeAuthorization : RestrictionsReceiver() {
}

override fun onReceive(context: Context, intent: Intent) {
onRequestReactedByUser(context, when {
intent.action == ACTION_AUTHORIZE -> true
intent.action == ACTION_REFUSE -> false
else -> return super.onReceive(context, intent)
}, intent.data?.schemeSpecificPart, intent.getStringExtra(EXTRA_PACKAGE_NAME), intent.getParcelableExtra(EXTRA_USER), intent.getStringExtra(REQUEST_KEY_DATA))
val pkg = intent.getStringExtra(EXTRA_PACKAGE_NAME) ?: return
val user : UserHandle = intent.getParcelableExtra(EXTRA_USER) ?: return
onRequestReactedByUser(context, when (intent.action) {
ACTION_AUTHORIZE -> true
ACTION_REFUSE -> false
else -> return super.onReceive(context, intent)
}, intent.data?.schemeSpecificPart, pkg, user, intent.getStringExtra(REQUEST_KEY_DATA) ?: return)
}

private fun onRequestReactedByUser(context: Context, authorized: Boolean, requestId: String?, pkg: String, user: UserHandle, delegation: String) {
Expand All @@ -105,11 +107,10 @@ class DelegatedScopeAuthorization : RestrictionsReceiver() {
}
}

private fun logAndToast(context: Context?, pkg: String?, message: String?) {
private fun logAndToast(context: Context?, pkg: String?, message: String) {
Log.w(TAG, message)
pkg?.let { Apps.of(context).getAppInfo(it) }?.flags?.apply { and(ApplicationInfo.FLAG_TEST_ONLY) != 0 }?.also {
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
}
Toast.makeText(context, message, Toast.LENGTH_LONG).show() }
}

class Initializer : PseudoContentProvider() { override fun onCreate(): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ public class NotificationManagerExtender extends NotificationManager {
}

public NotificationManagerExtender(final Context context) {
super(context, new Handler());
mDelegate = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class PendingIntentShuttle: BroadcastReceiver() {
private fun <R> Continuation<R>.resume(result: Int, extras: Bundle?, procedureClass: Class<*>? = null) = when (result) {
Activity.RESULT_OK -> resume(@Suppress("UNCHECKED_CAST") (extras?.get(null) as R))
RESULT_FIRST_USER -> resumeWithException(extras?.get(null) as Throwable)
else -> resumeWithException(RuntimeException("Error shuttling ${procedureClass ?: ""}")) }
else -> resumeWithException(RuntimeException("Error shuttling ${procedureClass ?: ""} (code $result)")) }

@ProfileUser fun sendToParentProfileByActivityIfNotYet(context: Context) {
if (mSentByActivity) return // Activity start is relatively heavy and cross-profile toast will be shown.
Expand Down
1 change: 0 additions & 1 deletion shared/src/main/java/com/oasisfeng/island/util/Hacks.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ public class Hacks {
@Hack.Fallback(-1) int checkOpNoThrow(int op, int uid, String pkg);
@RequiresPermission(GET_APP_OPS_STATS) @Nullable List<PackageOps> getOpsForPackage(int uid, String pkg, @Nullable int[] ops);
@RequiresPermission(GET_APP_OPS_STATS) @Nullable List<PackageOps> getPackagesForOps(@Nullable int[] ops);
@RequiresPermission(GET_APP_OPS_STATS) @Nullable List<PackageOps> getPackagesForOps(@Nullable String[] ops);
void setMode(int code, int uid, String packageName, @Mode int mode);
void setUidMode(String appOp, int uid, @Mode int mode);
void setRestriction(int code,/* @AttributeUsage */int usage, @Mode int mode, @Nullable String[] exceptionPackages);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import java.util.*
Log.w(TAG, "App is unavailable: $ssp")
NotificationIds.IslandAppWatcher.cancel(context, ssp) }
ACTION_REVOKE_PERMISSION -> {
val pkg = data.scheme; val policies = DevicePolicies(context)
val pkg = data.scheme!!; val policies = DevicePolicies(context)
val hidden = policies.invoke(DPM::isApplicationHidden, pkg)
if (hidden) policies.setApplicationHiddenWithoutAppOpsSaver(pkg, false) // setPermissionGrantState() only works for unfrozen app
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.Icon
import android.os.Build.VERSION.SDK_INT
import android.os.Build.VERSION_CODES.*
import android.os.Build.VERSION_CODES.O
import android.os.Build.VERSION_CODES.P
import android.os.Build.VERSION_CODES.Q
import android.os.Bundle
import android.os.IBinder
import android.os.UserHandle
Expand Down

0 comments on commit eaee381

Please sign in to comment.