2015-12-03 13 views
13

Interfejs API poziomu 23 dodano isPermissionRevokedByPolicy() on PackageManager. Przypuszcza się, aby powrócić false jeśli wymagane jest zezwolenie zablokowany na pewien pakiet „polityka”:Jak wypróbować zwykli programiści isPermissionRevokedByPolicy()?

Zazwyczaj właściciel urządzenia lub właściciel profilu może stosować taką politykę.

Czy jest coś, że programista może zrobić, aby spowodować isPermissionRevokedByPolicy() wrócić false jakiegoś połączeniu opakowanie/uprawnień, krótki przeżywa cały Android for Work zestaw shenanigans?

+0

Czy znalazłeś coś na ten temat? Sądzę, że jedynym sposobem na sprawdzenie może być użycie aplikacji Test DPC. To open source, ale wciąż wiele pracy po to, by przetestować jedną z metod. https://github.com/googlesamples/android-testdpc – fasteque

+0

@fasteque: Nie, nie mam odpowiedzi, dlatego nagroda jest nadal zaległa. W pewnym momencie włączyłem test DPC do "całego zestawu Shenanigans z Android for Work". Test DPC jest zdecydowanie niedostatecznie udokumentowany, nie mam pojęcia, jak zmapować elementy z tej strony "Zarządzaj uprawnieniami aplikacji" do rzeczywistych uprawnień Androida, które mogą być objęte przez 'isPermissionRevokedByPolicy()', itp. – CommonsWare

Odpowiedz

7

Oczywiście, mogę się mylić, ale wygląda na to, że krótka odpowiedź brzmi "nie, nie ma", niestety.

trochę bardziej rozszerzoną odpowiedź: Oto kod z ApplicationPackageManager:

@Override 
public boolean isPermissionRevokedByPolicy(String permName, String pkgName) { 
    try { 
     return mPM.isPermissionRevokedByPolicy(permName, pkgName, mContext.getUserId()); 
    } catch (RemoteException e) { 
     throw new RuntimeException("Package manager has died", e); 
    } 
} 

gdzie MPM -

private final IPackageManager mPM; 

To jest zainicjowany w konstruktorze, który jest nazywany przez ContextImpl.getPackageManager() :

@Override 
public PackageManager getPackageManager() { 
    if (mPackageManager != null) { 
     return mPackageManager; 
    } 

    IPackageManager pm = ActivityThread.getPackageManager(); 
    if (pm != null) { 
     // Doesn't matter if we make more than one instance. 
     return (mPackageManager = new ApplicationPackageManager(this, pm)); 
    } 

    return null; 
} 

(source code)

Idąc głębiej i patrząc ActivityThread.getPackageManager():

public static IPackageManager getPackageManager() { 
    if (sPackageManager != null) { 
     //Slog.v("PackageManager", "returning cur default = " + sPackageManager); 
     return sPackageManager; 
    } 
    IBinder b = ServiceManager.getService("package"); 
    //Slog.v("PackageManager", "default service binder = " + b); 
    sPackageManager = IPackageManager.Stub.asInterface(b); 
    //Slog.v("PackageManager", "default service = " + sPackageManager); 
    return sPackageManager; 
} 

(source code)

Wszystkie te kroki robiłem znaleźć rzeczywiste wdrożenie isPermissionRevokedByPolicy btw. Potem musiałem znaleźć, kto rozszerza IPackageManager.Stub - jest to PackageManagerService (source code).

Więc tutaj jest rzeczywista realizacja:

@Override 
public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 
    if (UserHandle.getCallingUserId() != userId) { 
     mContext.enforceCallingPermission(
       android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 
       "isPermissionRevokedByPolicy for user " + userId); 
    } 
    if (checkPermission(permission, packageName, userId) 
      == PackageManager.PERMISSION_GRANTED) { 
     return false; 
    } 
    final long identity = Binder.clearCallingIdentity(); 
    try { 
     final int flags = getPermissionFlags(permission, packageName, userId); 
     return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 
    } finally { 
     Binder.restoreCallingIdentity(identity); 
    } 
} 

Potencjalnie do "fake" status konkretnej zgody, to że trzeba włamać checkPermission i getPermissionFlags metod. Problem, obawiam się, nie istnieje żaden oczywisty sposób, aby nakarmić ApplicationPackageManager z overriden PackageManagerService, przynajmniej bez refleksji.

+0

Dzięki, ale niekoniecznie próbuję udawać odwołanie. Po prostu chcę uzyskać tę metodę zwracania "true" przy najmniejszym wysiłku.Na przykład: robi ['setCameraDisabled()' na 'DevicePolicyManager'] (http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setCameraDisabled%28android.content.ComponentName,%20boolean%29) spowodować 'isPermissionRevokedByPolicy()' dla 'Manifest.permission.CAMERA' zwrócić" true "? 'setCameraDisabled()' może być wywołane przez zwykłego administratora urządzenia, niekoniecznie właściciela urządzenia, właściciela polisy lub inne rzeczy z Android for Work. – CommonsWare

+0

@CommonsWare Tak, mogę być trochę niedokładny w pisaniu, koncentrując się szczególnie na unieważnieniu w tekście, ale niemniej jednak jest to prawdą w przypadku wszelkiego fałszerstwa. O setCameraDisabled() - pomyślę o tym więcej. Jeśli coś przyjdzie mi do głowy - zaktualizuję odpowiedź. –

+0

@CommonsWare setCameraDiabled() nie powoduje, że isPermissionRevokedByPolicy() zwróci true. To jest naprawdę mylące, dlaczego istnieje wiele apisów do sterowania funkcjami urządzenia. Zgodnie z moim rozumieniem zarządzanie zarządzeniami jest takie samo jak administrowanie urządzeniem z kilkoma dodatkowymi rzeczami. może być w Google może myśleć o wyeliminowaniu nadmiarowych api w przyszłości. Proszę, popraw mnie jeśli się mylę. – 7383

0

Nie sądzę, że istnieje bezpośredni sposób. Ale jako obejście, jeśli pakiet uruchomieniowy może zostać zmieniony, to ispermissionrevokedbypolicy() zwróci false. Ale czuję, że to też będzie trudna część.

Powiązane problemy