您的位置:首页 > 移动开发 > Android开发

Android M 概率跳不过google开机向导原因分析

2016-03-10 10:07 886 查看
更新:
     google更新开机向导APK后,我们可以通过点击上一步,再重新进wifi界面.多试几次,可能就可以跳过连wifi界面了.(也有变态的解法,判断google的开机向导activity,延迟个5-10s启动),留给FRP service 更多时间.

      同时,再国内环境,如果插了SIM卡有数据连接的话,机器会一直卡在检查网络界面,不管以前是否登录过google账号.

原因是:
第一次eng刷机开机,机器初始任务多,手机运行慢,如果手机在10s内没有取到killswitch的token是否存在的结果的话,wifi界面就没法跳过。

代码流程分析:
反编译google的开机向导后,我们从WifiSettingsWrapper.onStartSubactivity()里面可以知道,在这个方法返回true的时候NetworkRequirementHelper.isNetworkRequired(),wifi界面是没法skip的。
往下跟到----->FrpHelper.isChallengeRequired() ------> FrpStatus. getFrpStatus()
public static FrpStatus getFrpStatus()
{
FrpTask localFrpTask = getFrpRequiredTask();
if ((localFrpTask.getStatus() != AsyncTask.Status.FINISHED) ||(localFrpTask.isCancelled()));
……
}
可以看出如果localFrpTask没有完成,或者localFrpTask已经cancel了的话,getFrpStatus()会返回null,同时isChallengeRequired会返回true,也就是wifi界面没法skip

同时FrpHelper在实例的时候就会loadFrpStatus()也就是会去在后台跑localFrpTask,也就是FrpTask,看FrpTask类的doInBackground方法。
protected FrpHelper.FrpStatus doInBackground(Void[]paramArrayOfVoid)
{
FrpHelper.FrpStatus localFrpStatus = new FrpHelper.FrpStatus();
this.mHandler.postDelayed(this.mTimeoutRunnable,10000L);
try
{
localFrpStatus.challengeRequired =FrpHelper.-get0(FrpHelper.this).isChallengeRequired();
localFrpStatus.supported =FrpHelper.-get0(FrpHelper.this).isChallengeSupported();
Log.i("SetupWizard.FrpHelper", "FRP status: "+ localFrpStatus);
this.mHandler.removeCallbacks(this.mTimeoutRunnable);
return localFrpStatus;
}
catch (NullPointerException localNullPointerException)
{
while (true)
Log.wtf("SetupWizard.FrpHelper", "Exceptiongetting FRP challenge state", localNullPointerException);
}
}

从黄色高亮的代码可以看出10s后,如果task没有完,就会执行mTimeoutRunnable
privatefinal Runnable mTimeoutRunnable = new Runnable()
{
public void run()
{
if (FrpHelper.FrpTask.this.getStatus() ==AsyncTask.Status.RUNNING)
FrpHelper.FrpTask.this.cancel(true);
}
};
在mTimeoutRunnable里面会把这个后台task给cancel掉。

我们再返回看前面的getFrpStatus()方法,这个方法会返回null。
我们再通过smail代码看isChallengeRequired()方法的返回值:

.method publicstatic isChallengeRequired()Z
.locals 2

.prologue
.line 54
invoke-static{},Lcom/google/android/setupwizard/util/FrpHelper;->getFrpStatus()Lcom/google/android/setupwizard/util/FrpHelper$FrpStatus;

move-result-object v0

.line 55
.local v0,"frpStatus":Lcom/google/android/setupwizard/util/FrpHelper$FrpStatus;
if-eqzv0, :cond_0

iget-booleanv1, v0,Lcom/google/android/setupwizard/util/FrpHelper$FrpStatus;->challengeRequired:Z

:goto_0
return v1

:cond_0
const/4 v1,0x1

goto:goto_0
.end method

关键地方就是if-eqzv0,:cond_0,if-eqz意思是如果v0(frpStatus)是否等于Zreo,也就是null。恰好我们的frpStatus的值就是null。跟到cond_0,发现给了v1赋值1,也就是true,再跟到goto_0,这里直接把v1返回了,也就是返回了true。
所以wifi界面就跳不过了。

从抓的log里面可以证实上述运行逻辑:

01-0616:55:02.269 I/SetupWizard.FrpHelper( 5151): FRP status: supported:true, challengeRequired: false
…….
01-0616:55:02.593 W/SetupWizard.FrpHelper( 5151):FRPtask cancelled, butchallengeRequired=false

我在AsyncTask的cancel(booleanmayInterruptIfRunning)方法里面打出的回调栈的log:
01-0619:25:27.587 4109 4109 E fuyao : cancle call stackisjava.lang.Exception
01-0619:25:27.587 4109 4109 E fuyao : atandroid.os.AsyncTask.cancel(AsyncTask.java:482)
01-0619:25:27.587 4109 4109 E fuyao : atcom.google.android.setupwizard.util.FrpHelper$FrpTask$1.run(FrpHelper.java:127)
01-0619:25:27.587 4109 4109 E fuyao : atandroid.os.Handler.handleCallback(Handler.java:739)
01-0619:25:27.587 4109 4109 E fuyao : atandroid.os.Handler.dispatchMessage(Handler.java:95)
01-0619:25:27.587 4109 4109 E fuyao : atandroid.os.Looper.loop(Looper.java:148)
01-0619:25:27.587 4109 4109 E fuyao : atandroid.app.ActivityThread.main(ActivityThread.java:5417)
01-0619:25:27.587 4109 4109 E fuyao : atjava.lang.reflect.Method.invoke(Native Method)
01-0619:25:27.587 4109 4109 E fuyao : atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
01-0619:25:27.587 4109 4109 E fuyao : atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

PS:反编译后的java代码逻辑有些混乱,我们可以通过查看反编译的smali代码来帮助我们确认正常的逻辑
对比了AndroidL的Setupwizard,是没有这个10s的要求的。

总结:
Google就是个坑- -!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息